diff options
author | Arthur de Jong <arthur@arthurdejong.org> | 2006-12-21 20:55:55 +0100 |
---|---|---|
committer | Arthur de Jong <arthur@arthurdejong.org> | 2006-12-21 20:55:55 +0100 |
commit | fbc5ecfb8cf86d753b7c9a3b5b549a8f279666ab (patch) | |
tree | 5d008fb2963ef8a27da784ba851984f64678e6f0 /server | |
parent | 8366a3eb4a9032ca43cae9fccaa536182dcece04 (diff) |
rename server directory to nslcd
git-svn-id: http://arthurdejong.org/svn/nss-pam-ldapd/nss-ldapd@196 ef36b2f9-881f-0410-afb5-c4e39611909c
Diffstat (limited to 'server')
-rw-r--r-- | server/Makefile.am | 33 | ||||
-rw-r--r-- | server/alias.c | 137 | ||||
-rw-r--r-- | server/common.c | 42 | ||||
-rw-r--r-- | server/common.h | 89 | ||||
-rw-r--r-- | server/dnsconfig.c | 188 | ||||
-rw-r--r-- | server/dnsconfig.h | 30 | ||||
-rw-r--r-- | server/ether.c | 231 | ||||
-rw-r--r-- | server/group.c | 1231 | ||||
-rw-r--r-- | server/host.c | 380 | ||||
-rw-r--r-- | server/ldap-nss.c | 4032 | ||||
-rw-r--r-- | server/ldap-nss.h | 611 | ||||
-rw-r--r-- | server/ldap-schema.c | 453 | ||||
-rw-r--r-- | server/ldap-schema.h | 303 | ||||
-rw-r--r-- | server/log.c | 187 | ||||
-rw-r--r-- | server/log.h | 60 | ||||
-rw-r--r-- | server/netgroup.c | 354 | ||||
-rw-r--r-- | server/network.c | 245 | ||||
-rw-r--r-- | server/nslcd.c | 656 | ||||
-rw-r--r-- | server/pagectrl.c | 224 | ||||
-rw-r--r-- | server/pagectrl.h | 45 | ||||
-rw-r--r-- | server/passwd.c | 273 | ||||
-rw-r--r-- | server/protocol.c | 198 | ||||
-rw-r--r-- | server/resolve.c | 352 | ||||
-rw-r--r-- | server/resolve.h | 118 | ||||
-rw-r--r-- | server/rpc.c | 206 | ||||
-rw-r--r-- | server/service.c | 302 | ||||
-rw-r--r-- | server/shadow.c | 189 | ||||
-rw-r--r-- | server/util.c | 1669 | ||||
-rw-r--r-- | server/util.h | 121 | ||||
-rw-r--r-- | server/xmalloc.c | 59 | ||||
-rw-r--r-- | server/xmalloc.h | 36 |
31 files changed, 0 insertions, 13054 deletions
diff --git a/server/Makefile.am b/server/Makefile.am deleted file mode 100644 index f451623..0000000 --- a/server/Makefile.am +++ /dev/null @@ -1,33 +0,0 @@ -# Makefile.am - use automake to generate Makefile.in -# -# Copyright (C) 2006 West Consulting -# Copyright (C) 2006 Arthur de Jong -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Library General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# 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 -# Library General Public License for more details. -# -# You should have received a copy of the GNU Library General Public -# License along with this library; if not, write to the Free -# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, -# MA 02110-1301 USA - -sbin_PROGRAMS = nslcd -AM_CFLAGS = -pthread - -nslcd_SOURCES = nslcd.c ../nslcd.h ../nslcd-common.h \ - log.c log.h \ - xmalloc.c xmalloc.h \ - common.c common.h \ - alias.c ether.c group.c host.c netgroup.c network.c \ - passwd.c protocol.c rpc.c service.c shadow.c \ - dnsconfig.c dnsconfig.h ldap-nss.c ldap-nss.h \ - ldap-schema.c ldap-schema.h pagectrl.c pagectrl.h \ - resolve.c resolve.h util.c util.h -nslcd_LDADD = @nslcd_LIBS@ diff --git a/server/alias.c b/server/alias.c deleted file mode 100644 index 4698f1b..0000000 --- a/server/alias.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - alias.c - alias entry lookup routines - This file was part of the nss_ldap library (as ldap-alias.c) - which has been forked into the nss-ldapd library. - - Copyright (C) 1997-2005 Luke Howard - Copyright (C) 2006 West Consulting - Copyright (C) 2006 Arthur de Jong - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1301 USA -*/ - -#include "config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <lber.h> -#include <ldap.h> -#include <errno.h> -#include <aliases.h> -#if defined(HAVE_THREAD_H) -#include <thread.h> -#elif defined(HAVE_PTHREAD_H) -#include <pthread.h> -#endif - -#include "ldap-nss.h" -#include "util.h" -#include "common.h" -#include "log.h" - -static enum nss_status _nss_ldap_parse_alias( - LDAPMessage *e,struct ldap_state *pvt,void *result, - char *buffer,size_t buflen) -{ - - struct aliasent *alias=(struct aliasent *)result; - enum nss_status stat; - - stat=_nss_ldap_getrdnvalue(e,ATM(LM_ALIASES,cn),&alias->alias_name,&buffer,&buflen); - if (stat != NSS_STATUS_SUCCESS) - return stat; - - stat=_nss_ldap_assign_attrvals(e,AT(rfc822MailMember),NULL,&alias->alias_members,&buffer,&buflen,&alias->alias_members_len); - - return stat; -} - -static int write_alias(LDAPMessage *e,struct ldap_state *pvt,FILE *fp) -{ - int stat; - if ((stat=_nss_ldap_write_rndvalue(fp,e,ATM(LM_ALIASES,cn)))!=NSLCD_RESULT_SUCCESS) - return stat; - if ((stat=_nss_ldap_write_attrvals(fp,e,AT(rfc822MailMember)))!=NSLCD_RESULT_SUCCESS) - return stat; - return NSLCD_RESULT_SUCCESS; -} - - -/* macros for expanding the NSLCD_ALIAS macro */ -#define NSLCD_STRING(field) WRITE_STRING(fp,field) -#define NSLCD_STRINGLIST(field) WRITE_STRINGLIST_NUM(fp,field,result.alias_members_len) -#define ALIAS_NAME result.alias_name -#define ALIAS_RCPTS result.alias_members - -int nslcd_alias_byname(FILE *fp) -{ - int32_t tmpint32; - char *name; - struct ldap_args a; - /* read request parameters */ - READ_STRING_ALLOC(fp,name); - /* log call */ - log_log(LOG_DEBUG,"nslcd_alias_byname(%s)",name); - /* write the response header */ - WRITE_INT32(fp,NSLCD_VERSION); - WRITE_INT32(fp,NSLCD_ACTION_ALIAS_BYNAME); - /* do the LDAP request */ - LA_INIT(a); - LA_STRING(a)=name; - LA_TYPE(a)=LA_TYPE_STRING; - _nss_ldap_searchbyname(&a,_nss_ldap_filt_getaliasbyname,LM_ALIASES,fp,write_alias); - /* no more need for this */ - free(name); - WRITE_FLUSH(fp); - /* we're done */ - return 0; -} - -int nslcd_alias_all(FILE *fp) -{ - int32_t tmpint32,tmp2int32; - static struct ent_context *alias_context; - /* these are here for now until we rewrite the LDAP code */ - struct aliasent result; - char buffer[1024]; - int errnop; - int retv; - /* log call */ - log_log(LOG_DEBUG,"nslcd_alias_all()"); - /* write the response header */ - WRITE_INT32(fp,NSLCD_VERSION); - WRITE_INT32(fp,NSLCD_ACTION_ALIAS_ALL); - /* initialize context */ - if (_nss_ldap_ent_context_init(&alias_context)==NULL) - return -1; - /* loop over all results */ - while ((retv=nss2nslcd(_nss_ldap_getent(&alias_context,&result,buffer,1024,&errnop,_nss_ldap_filt_getaliasent,LM_ALIASES,_nss_ldap_parse_alias)))==NSLCD_RESULT_SUCCESS) - { - /* write the result */ - WRITE_INT32(fp,retv); - NSLCD_ALIAS; - } - /* write the final result code */ - WRITE_INT32(fp,retv); - WRITE_FLUSH(fp); - /* FIXME: if a previous call returns what happens to the context? */ - _nss_ldap_enter(); - _nss_ldap_ent_context_release(alias_context); - _nss_ldap_leave(); - /* we're done */ - return 0; -} diff --git a/server/common.c b/server/common.c deleted file mode 100644 index 33d203d..0000000 --- a/server/common.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - common.c - common server code routines - This file is part of the nss-ldapd library. - - Copyright (C) 2006 West Consulting - Copyright (C) 2006 Arthur de Jong - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1301 USA -*/ - -#include "config.h" - -#include "nslcd.h" -#include "common.h" - -/* translates a nslcd return code (as defined in nslcd.h) to - a nss code (as defined in nss.h) */ -/* FIXME: this is a temporary hack, get rid of it */ -int nss2nslcd(enum nss_status code) -{ - switch (code) - { - case NSS_STATUS_UNAVAIL: return NSLCD_RESULT_UNAVAIL; - case NSS_STATUS_NOTFOUND: return NSLCD_RESULT_NOTFOUND; - case NSS_STATUS_SUCCESS: return NSLCD_RESULT_SUCCESS; -/* case NSS_STATUS_TRYAGAIN: return NSLCD_RS_SMALLBUF; */ - default: return NSLCD_RESULT_UNAVAIL; - } -} diff --git a/server/common.h b/server/common.h deleted file mode 100644 index 42f47ea..0000000 --- a/server/common.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - common.h - common server code routines - This file is part of the nss-ldapd library. - - Copyright (C) 2006 West Consulting - Copyright (C) 2006 Arthur de Jong - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1301 USA -*/ - -#ifndef _SERVER_COMMON_H -#define _SERVER_COMMON_H 1 - -#include "nslcd.h" -#include "nslcd-common.h" - - -/* translates a nss code (as defined in nss.h) to a - nslcd return code (as defined in nslcd.h) */ -/* FIXME: this is a temporary hack, get rid of it */ -#include <nss.h> -int nss2nslcd(enum nss_status code); - - -/* macros for basic read and write operations, the following - ERROR_OUT* marcos define the action taken on errors - the stream is not closed because the caller closes the - stream */ - -#define ERROR_OUT_WRITEERROR(fp) \ - log_log(LOG_WARNING,"error writing to client"); \ - return -1; - -#define ERROR_OUT_READERROR(fp) \ - log_log(LOG_WARNING,"error reading from client"); \ - return -1; - -#define ERROR_OUT_ALLOCERROR(fp) \ - log_log(LOG_ERR,"error allocating memory"); \ - return -1; - - -/* these are the different functions that handle the database - specific actions, see nslcd.h for the action descriptions */ -int nslcd_alias_byname(FILE *fp); -int nslcd_alias_all(FILE *fp); -int nslcd_ether_byname(FILE *fp); -int nslcd_ether_byether(FILE *fp); -int nslcd_ether_all(FILE *fp); -int nslcd_group_byname(FILE *fp); -int nslcd_group_bygid(FILE *fp); -int nslcd_group_bymember(FILE *fp); -int nslcd_group_all(FILE *fp); -int nslcd_host_byname(FILE *fp); -int nslcd_host_byaddr(FILE *fp); -int nslcd_host_all(FILE *fp); -int nslcd_netgroup_byname(FILE *fp); -int nslcd_network_byname(FILE *fp); -int nslcd_network_byaddr(FILE *fp); -int nslcd_network_all(FILE *fp); -int nslcd_passwd_byname(FILE *fp); -int nslcd_passwd_byuid(FILE *fp); -int nslcd_passwd_all(FILE *fp); -int nslcd_protocol_byname(FILE *fp); -int nslcd_protocol_bynumber(FILE *fp); -int nslcd_protocol_all(FILE *fp); -int nslcd_rpc_byname(FILE *fp); -int nslcd_rpc_bynumber(FILE *fp); -int nslcd_rpc_all(FILE *fp); -int nslcd_service_byname(FILE *fp); -int nslcd_service_bynumber(FILE *fp); -int nslcd_service_all(FILE *fp); -int nslcd_shadow_byname(FILE *fp); -int nslcd_shadow_all(FILE *fp); - -#endif /* not _SERVER_COMMON_H */ diff --git a/server/dnsconfig.c b/server/dnsconfig.c deleted file mode 100644 index 12b0997..0000000 --- a/server/dnsconfig.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - dnsconfig.c - lookup code for DNS SRV records - This file was part of the nss_ldap library which has been - forked into the nss-ldapd library. - - Copyright (C) 1997-2005 Luke Howard - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1301 USA -*/ - -/* - * Support DNS SRV records. I look up the SRV record for - * _ldap._tcp.gnu.org. - * and build the DN DC=gnu,DC=org. - * Thanks to Assar & co for resolve.[ch]. - */ - -#include "config.h" - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <sys/param.h> -#include <netdb.h> -#include <syslog.h> -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <resolv.h> -#include <string.h> -#ifdef HAVE_LBER_H -#include <lber.h> -#endif -#ifdef HAVE_LDAP_H -#include <ldap.h> -#endif - -#include "ldap-nss.h" -#include "util.h" -#include "resolve.h" -#include "dnsconfig.h" - -#define DC_ATTR "DC" -#define DC_ATTR_AVA DC_ATTR"=" -#define DC_ATTR_AVA_LEN (sizeof(DC_ATTR_AVA) - 1) - -/* map gnu.org into DC=gnu,DC=org */ -static enum nss_status -_nss_ldap_getdnsdn (char *src_domain, - char **rval, char **buffer, size_t * buflen) -{ - char *p; - int len = 0; -#ifdef HAVE_STRTOK_R - char *st = NULL; -#endif - char *bptr; - char *domain, *domain_copy; - - /* we need to take a copy of domain, because strtok() modifies - * it in place. Bad. - */ - domain_copy = strdup (src_domain); - if (domain_copy == NULL) - { - return NSS_STATUS_TRYAGAIN; - } - - domain = domain_copy; - - bptr = *rval = *buffer; - **rval = '\0'; - -#ifndef HAVE_STRTOK_R - while ((p = strtok (domain, "."))) -#else - while ((p = strtok_r (domain, ".", &st))) -#endif - { - len = strlen (p); - - if (*buflen < (size_t) (len + DC_ATTR_AVA_LEN + 1 /* D C = [,|\0] */ )) - { - free (domain_copy); - return NSS_STATUS_TRYAGAIN; - } - - if (domain == NULL) - { - strcpy (bptr, ","); - bptr++; - } - else - { - domain = NULL; - } - - strcpy (bptr, DC_ATTR_AVA); - bptr += DC_ATTR_AVA_LEN; - - strcpy (bptr, p); - bptr += len; /* don't include comma */ - *buffer += len + DC_ATTR_AVA_LEN + 1; - *buflen -= len + DC_ATTR_AVA_LEN + 1; - } - - if (bptr != NULL) - { - (*rval)[bptr - *rval] = '\0'; - } - - free (domain_copy); - - return NSS_STATUS_SUCCESS; -} - -enum nss_status -_nss_ldap_mergeconfigfromdns (struct ldap_config * result, - char **buffer, size_t *buflen) -{ - enum nss_status stat = NSS_STATUS_SUCCESS; - struct dns_reply *r; - struct resource_record *rr; - char domain[MAXHOSTNAMELEN + 1]; - char *pDomain; - char uribuf[NSS_BUFSIZ]; - - if ((_res.options & RES_INIT) == 0 && res_init () == -1) - { - return NSS_STATUS_UNAVAIL; - } - - if (result->ldc_srv_domain != NULL) - pDomain = result->ldc_srv_domain; - else - { - snprintf (domain, sizeof (domain), "_ldap._tcp.%s.", _res.defdname); - pDomain = domain; - } - - r = dns_lookup (pDomain, "srv"); - if (r == NULL) - { - return NSS_STATUS_NOTFOUND; - } - - /* XXX sort by priority */ - for (rr = r->head; rr != NULL; rr = rr->next) - { - if (rr->type == T_SRV) - { - snprintf (uribuf, sizeof(uribuf), "ldap%s:%s:%d", - (rr->u.srv->port == LDAPS_PORT) ? "s" : "", - rr->u.srv->target, - rr->u.srv->port); - - stat = _nss_ldap_add_uri (result, uribuf, buffer, buflen); - if (stat != NSS_STATUS_SUCCESS) - { - break; - } - } - } - - dns_free_data (r); - stat = NSS_STATUS_SUCCESS; - - if (result->ldc_base == NULL) - { - stat = _nss_ldap_getdnsdn (_res.defdname, &result->ldc_base, - buffer, buflen); - } - - return stat; -} - diff --git a/server/dnsconfig.h b/server/dnsconfig.h deleted file mode 100644 index 479a717..0000000 --- a/server/dnsconfig.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - dnsconfig.c - lookup code for DNS SRV records - This file was part of the nss_ldap library which has been - forked into the nss-ldapd library. - - Copyright (C) 1997-2005 Luke Howard - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1301 USA -*/ - -#ifndef _LDAP_NSS_LDAP_DNSCONFIG_H -#define _LDAP_NSS_LDAP_DNSCONFIG_H - -enum nss_status _nss_ldap_mergeconfigfromdns (struct ldap_config * result, - char **buffer, size_t *buflen); - -#endif /* _LDAP_NSS_LDAP_DNSCONFIG_H */ diff --git a/server/ether.c b/server/ether.c deleted file mode 100644 index ab7b870..0000000 --- a/server/ether.c +++ /dev/null @@ -1,231 +0,0 @@ -/* - ether.c - ethernet address entry lookup routines - This file was part of the nss_ldap library (as ldap-ethers.c) - which has been forked into the nss-ldapd library. - - Copyright (C) 1997-2005 Luke Howard - Copyright (C) 2006 West Consulting - Copyright (C) 2006 Arthur de Jong - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1301 USA -*/ - -#include "config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <netdb.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <net/if.h> -#include <netinet/in.h> -#ifdef HAVE_LBER_H -#include <lber.h> -#endif -#ifdef HAVE_LDAP_H -#include <ldap.h> -#endif -#if defined(HAVE_THREAD_H) -#include <thread.h> -#elif defined(HAVE_PTHREAD_H) -#include <pthread.h> -#endif -#ifdef HAVE_NET_ROUTE_H -#include <net/route.h> -#endif -#ifdef HAVE_NETINET_IF_ETHER_H -#include <netinet/if_ether.h> -#endif -#ifdef HAVE_NETINET_ETHER_H -#include <netinet/ether.h> -#endif - -#include "ldap-nss.h" -#include "util.h" -#include "common.h" -#include "log.h" - -#ifndef HAVE_STRUCT_ETHER_ADDR -struct ether_addr { - u_int8_t ether_addr_octet[6]; -}; -#endif - -struct ether -{ - char *e_name; - struct ether_addr e_addr; -}; - -#ifdef NEW -static int write_ether(LDAPMessage *e,struct ldap_state *pvt,FILE *fp) -{ - int stat; - char buffer[1024]; - /* write NSLCD_STRING(ETHER_NAME) */ - stat=_nss_ldap_write_attrval(fp,e,ATM(LM_ETHERS,cn)); - if (stat!=NSLCD_RESULT_SUCCESS) - return stat; - /* write NSLCD_TYPE(ETHER_ADDR,u_int8_t[6]) */ - stat=_nss_ldap_write_attrval_ether(fp,e,AT(macAddress)); - - stat = _nss_ldap_assign_attrval (e, AT (macAddress), &saddr, - &buffer, &buflen); - if (stat != NSS_STATUS_SUCCESS || ((addr = ether_aton (saddr)) == NULL)) - return NSS_STATUS_NOTFOUND; - memcpy (ðer->e_addr, addr, sizeof (*addr)); - return NSLCD_RESULT_SUCCESS; -} -#endif /* NEW */ - -static enum nss_status -_nss_ldap_parse_ether (LDAPMessage * e, - struct ldap_state * pvt, - void *result, char *buffer, size_t buflen) -{ - struct ether *ether = (struct ether *) result; - char *saddr; - enum nss_status stat; - struct ether_addr *addr; - - stat = _nss_ldap_assign_attrval (e, ATM (LM_ETHERS, cn), - ðer->e_name, &buffer, &buflen); - if (stat != NSS_STATUS_SUCCESS) - return stat; - - stat = _nss_ldap_assign_attrval (e, AT (macAddress), &saddr, - &buffer, &buflen); - - if (stat != NSS_STATUS_SUCCESS || ((addr = ether_aton (saddr)) == NULL)) - return NSS_STATUS_NOTFOUND; - - memcpy (ðer->e_addr, addr, sizeof (*addr)); - - return NSS_STATUS_SUCCESS; -} - -/* macros for expanding the NSLCD_ETHER macro */ -#define NSLCD_STRING(field) WRITE_STRING(fp,field) -#define NSLCD_TYPE(field,type) WRITE_TYPE(fp,field,type) -#define ETHER_NAME result.e_name -#define ETHER_ADDR result.e_addr - -int nslcd_ether_byname(FILE *fp) -{ - int32_t tmpint32; - char *name; - struct ldap_args a; - /* these are here for now until we rewrite the LDAP code */ - struct ether result; - char buffer[1024]; - int errnop; - int retv; - /* read request parameters */ - READ_STRING_ALLOC(fp,name); - /* log call */ - log_log(LOG_DEBUG,"nslcd_ether_byname(%s)",name); - /* write the response header */ - WRITE_INT32(fp,NSLCD_VERSION); - WRITE_INT32(fp,NSLCD_ACTION_ETHER_BYNAME); - /* do the LDAP request */ - LA_INIT(a); - LA_STRING(a)=name; - LA_TYPE(a)=LA_TYPE_STRING; - retv=nss2nslcd(_nss_ldap_getbyname(&a,&result,buffer,1024,&errnop,_nss_ldap_filt_gethostton,LM_ETHERS,_nss_ldap_parse_ether)); - /* no more need for this string */ - free(name); - /* write the response */ - WRITE_INT32(fp,retv); - if (retv==NSLCD_RESULT_SUCCESS) - { - NSLCD_ETHER; - } - WRITE_FLUSH(fp); - /* we're done */ - return 0; -} - -int nslcd_ether_byether(FILE *fp) -{ - int32_t tmpint32; - struct ether_addr addr; - struct ldap_args a; - /* these are here for now until we rewrite the LDAP code */ - struct ether result; - char buffer[1024]; - int errnop; - int retv; - /* read request parameters */ - READ_TYPE(fp,addr,u_int8_t[6]); - /* log call */ - log_log(LOG_DEBUG,"nslcd_ether_byether(%s)",ether_ntoa(&addr)); - /* write the response header */ - WRITE_INT32(fp,NSLCD_VERSION); - WRITE_INT32(fp,NSLCD_ACTION_ETHER_BYETHER); - /* do the LDAP request */ - LA_INIT(a); - /* FIXME: this has a bug when the directory has 01:00:0e:... - and we're looking for 1:0:e:... (leading zeros) */ - LA_STRING(a)=ether_ntoa(&addr); - LA_TYPE(a)=LA_TYPE_STRING; - retv=nss2nslcd(_nss_ldap_getbyname(&a,&result,buffer,1024,&errnop,_nss_ldap_filt_getntohost,LM_ETHERS,_nss_ldap_parse_ether)); - /* write the response */ - WRITE_INT32(fp,retv); - if (retv==NSLCD_RESULT_SUCCESS) - { - NSLCD_ETHER; - } - WRITE_FLUSH(fp); - /* we're done */ - return 0; -} - -int nslcd_ether_all(FILE *fp) -{ - int32_t tmpint32; - static struct ent_context *ether_context; - /* these are here for now until we rewrite the LDAP code */ - struct ether result; - char buffer[1024]; - int errnop; - int retv; - /* log call */ - log_log(LOG_DEBUG,"nslcd_ether_all()"); - /* write the response header */ - WRITE_INT32(fp,NSLCD_VERSION); - WRITE_INT32(fp,NSLCD_ACTION_ETHER_ALL); - /* initialize context */ - if (_nss_ldap_ent_context_init(ðer_context)==NULL) - return -1; - /* loop over all results */ - while ((retv=nss2nslcd(_nss_ldap_getent(ðer_context,&result,buffer,1024,&errnop,_nss_ldap_filt_getetherent,LM_ETHERS,_nss_ldap_parse_ether)))==NSLCD_RESULT_SUCCESS) - { - /* write the result */ - WRITE_INT32(fp,retv); - NSLCD_ETHER; - } - /* write the final result code */ - WRITE_INT32(fp,retv); - WRITE_FLUSH(fp); - /* FIXME: if a previous call returns what happens to the context? */ - _nss_ldap_enter(); - _nss_ldap_ent_context_release(ether_context); - _nss_ldap_leave(); - /* we're done */ - return 0; -} diff --git a/server/group.c b/server/group.c deleted file mode 100644 index e537e96..0000000 --- a/server/group.c +++ /dev/null @@ -1,1231 +0,0 @@ -/* - group.c - group entry lookup routines - This file was part of the nss_ldap library (as ldap-grp.c) which - has been forked into the nss-ldapd library. - - Copyright (C) 1997-2006 Luke Howard - Copyright (C) 2006 West Consulting - Copyright (C) 2006 Arthur de Jong - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1301 USA -*/ - -#include "config.h" - -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#include <sys/types.h> -#include <sys/param.h> -#include <grp.h> -#include <errno.h> -#ifdef HAVE_LBER_H -#include <lber.h> -#endif -#ifdef HAVE_LDAP_H -#include <ldap.h> -#endif -#if defined(HAVE_THREAD_H) -#include <thread.h> -#elif defined(HAVE_PTHREAD_H) -#include <pthread.h> -#endif - -#include "ldap-nss.h" -#include "util.h" -#include "common.h" -#include "log.h" - -#ifdef HAVE_USERSEC_H -typedef struct ldap_initgroups_args -{ - char *grplist; - size_t listlen; - int depth; - struct name_list *known_groups; - int backlink; -} -ldap_initgroups_args_t; -#else -typedef struct ldap_initgroups_args -{ - gid_t group; - long int *start; - long int *size; - gid_t **groups; - long int limit; - int depth; - struct name_list *known_groups; - int backlink; -} -ldap_initgroups_args_t; -#endif /* HAVE_USERSEC_H */ - -#define LDAP_NSS_MAXGR_DEPTH 16 /* maximum depth of group nesting for getgrent()/initgroups() */ - -#if LDAP_NSS_NGROUPS > 64 -#define LDAP_NSS_BUFLEN_GROUP (NSS_BUFSIZ + (LDAP_NSS_NGROUPS * (sizeof (char *) + LOGNAME_MAX))) -#else -#define LDAP_NSS_BUFLEN_GROUP NSS_BUFSIZ -#endif /* LDAP_NSS_NGROUPS > 64 */ - -#ifndef LOGNAME_MAX -#define LOGNAME_MAX 8 -#endif /* LOGNAME_MAX */ - -#ifndef UID_NOBODY -#define UID_NOBODY (-2) -#endif - -#ifndef GID_NOBODY -#define GID_NOBODY UID_NOBODY -#endif - -static enum nss_status -ng_chase (const char *dn, ldap_initgroups_args_t * lia); - -static enum nss_status -ng_chase_backlink (const char ** membersOf, ldap_initgroups_args_t * lia); - -/* - * Range retrieval logic was reimplemented from example in - * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ldap/ldap/searching_using_range_retrieval.asp - */ - -static enum nss_status -do_parse_range (const char *attributeType, - const char *attributeDescription, int *start, int *end) -{ - enum nss_status stat = NSS_STATUS_NOTFOUND; - char *attribute; - size_t attributeTypeLength; - size_t attributeDescriptionLength; - char *p; -#ifdef HAVE_STRTOK_R - char *st = NULL; -#endif - - *start = 0; - *end = -1; - - if (strcasecmp (attributeType, attributeDescription) == 0) - { - return NSS_STATUS_SUCCESS; - } - - attributeDescriptionLength = strlen (attributeDescription); - attributeTypeLength = strlen (attributeType); - - if (attributeDescriptionLength < attributeTypeLength) - { - /* could not be a subtype */ - return NSS_STATUS_NOTFOUND; - } - - /* XXX need to copy as strtok() is destructive */ - attribute = strdup (attributeDescription); - if (attribute == NULL) - { - return NSS_STATUS_TRYAGAIN; - } - -#ifndef HAVE_STRTOK_R - for (p = strtok (attribute, ";"); p != NULL; p = strtok (NULL, ";")) -#else - for (p = strtok_r (attribute, ";", &st); - p != NULL; p = strtok_r (NULL, ";", &st)) -#endif /* !HAVE_STRTOK_R */ - { - char *q; - - if (p == attribute) - { - if (strcasecmp (p, attributeType) != 0) - { - free (attribute); - return NSS_STATUS_NOTFOUND; - } - } - else if (strncasecmp (p, "range=", sizeof ("range=") - 1) == 0) - { - p += sizeof ("range=") - 1; - - q = strchr (p, '-'); - if (q == NULL) - { - free (attribute); - return NSS_STATUS_NOTFOUND; - } - - *q++ = '\0'; - - *start = strtoul (p, (char **) NULL, 10); - if (strcmp (q, "*") == 0) - *end = -1; - else - *end = strtoul (q, (char **) NULL, 10); - - stat = NSS_STATUS_SUCCESS; - break; - } - } - - free (attribute); - return stat; -} - -static enum nss_status -do_get_range_values (LDAPMessage * e, - const char *attributeType, - int *start, int *end, char ***pGroupMembers) -{ - enum nss_status stat = NSS_STATUS_NOTFOUND; - BerElement *ber = NULL; - char *attribute; - - *pGroupMembers = NULL; - - for (attribute = _nss_ldap_first_attribute (e, &ber); - attribute != NULL; attribute = _nss_ldap_next_attribute (e, ber)) - { - stat = do_parse_range (attributeType, attribute, start, end); - if (stat == NSS_STATUS_SUCCESS) - { - *pGroupMembers = _nss_ldap_get_values (e, attribute); - if (*pGroupMembers == NULL) - { - stat = NSS_STATUS_NOTFOUND; - } - else if ((*pGroupMembers)[0] == NULL) - { - ldap_value_free (*pGroupMembers); - *pGroupMembers = NULL; - stat = NSS_STATUS_NOTFOUND; - } - } - -#ifdef HAVE_LDAP_MEMFREE - ldap_memfree (attribute); -#endif - - if (stat == NSS_STATUS_SUCCESS) - break; - } - - if (ber != NULL) - ber_free (ber, 0); - - return stat; -} - -/* - * Format an attribute with description as: - * attribute;range=START-END - */ -static enum nss_status -do_construct_range_attribute (const char *attribute, - int start, - int end, - char **buffer, - size_t * buflen, - const char **pAttributeWithRange) -{ - size_t len; - char startbuf[32], endbuf[32]; - - snprintf (startbuf, sizeof (startbuf), "%u", start); - - if (end != -1) - snprintf (endbuf, sizeof (endbuf), "%u", end); - else - snprintf (endbuf, sizeof (endbuf), "*"); - - len = strlen (attribute) + sizeof (";range=") - 1; - len += strlen (startbuf) + 1 /* - */ + strlen (endbuf); - len++; /* \0 */ - - if (*buflen < len) - return NSS_STATUS_TRYAGAIN; - - *pAttributeWithRange = *buffer; - - snprintf (*buffer, len, "%s;range=%s-%s", attribute, startbuf, endbuf); - - *buffer += len; - *buflen -= len; - - return NSS_STATUS_SUCCESS; -} - -/* - * Expand group members, including nested groups - */ -static enum nss_status -do_parse_group_members (LDAPMessage * e, - char ***pGroupMembers, - size_t * pGroupMembersCount, - size_t * pGroupMembersBufferSize, - int *pGroupMembersBufferIsMalloced, - char **buffer, size_t * buflen, - int *depth, - struct name_list **pKnownGroups) /* traversed groups */ -{ - enum nss_status stat = NSS_STATUS_SUCCESS; - char **dnValues = NULL; - char **uidValues = NULL; - char **groupMembers; - size_t groupMembersCount, i; - char **valiter; - /* support for range retrieval */ - const char *uniquemember_attr; - const char *uniquemember_attrs[2]; - LDAPMessage *res = NULL; - int start, end = 0; - char *groupdn = NULL; - - uniquemember_attr = ATM (LM_GROUP, uniqueMember); - - uniquemember_attrs[0] = uniquemember_attr; - uniquemember_attrs[1] = NULL; - - if (*depth > LDAP_NSS_MAXGR_DEPTH) - { - return NSS_STATUS_NOTFOUND; - } - - i = *pGroupMembersCount; /* index of next member */ - groupMembers = *pGroupMembers; - - groupdn = _nss_ldap_get_dn (e); - if (groupdn == NULL) - { - stat = NSS_STATUS_NOTFOUND; - goto out; - } - - if (_nss_ldap_namelist_find (*pKnownGroups, groupdn)) - { - stat = NSS_STATUS_NOTFOUND; - goto out; - } - - /* store group DN for nested group loop detection */ - stat = _nss_ldap_namelist_push (pKnownGroups, groupdn); - if (stat != NSS_STATUS_SUCCESS) - { - goto out; - } - - do - { - if (e == NULL) - { - stat = NSS_STATUS_NOTFOUND; - goto out; - } - - groupMembersCount = 0; /* number of members in this group */ - - (void) do_get_range_values (e, uniquemember_attrs[0], &start, &end, &dnValues); - if (dnValues != NULL) - { - groupMembersCount += ldap_count_values (dnValues); - } - - uidValues = _nss_ldap_get_values (e, ATM (LM_GROUP, memberUid)); - if (uidValues != NULL) - { - groupMembersCount += ldap_count_values (uidValues); - } - - /* - * Check whether we need to increase the group membership buffer. - * As an optimization the buffer is preferentially allocated off - * the stack - */ - if ((i + groupMembersCount) * sizeof (char *) >= - *pGroupMembersBufferSize) - { - *pGroupMembersBufferSize = - (i + groupMembersCount + 1) * sizeof (char *); - *pGroupMembersBufferSize += - (LDAP_NSS_NGROUPS * sizeof (char *)) - 1; - *pGroupMembersBufferSize -= - (*pGroupMembersBufferSize % - (LDAP_NSS_NGROUPS * sizeof (char *))); - - if (*pGroupMembersBufferIsMalloced == 0) - { - groupMembers = *pGroupMembers; - *pGroupMembers = NULL; /* force malloc() */ - } - - *pGroupMembers = - (char **) realloc (*pGroupMembers, *pGroupMembersBufferSize); - if (*pGroupMembers == NULL) - { - *pGroupMembersBufferIsMalloced = 0; /* don't try to free */ - stat = NSS_STATUS_TRYAGAIN; - goto out; - } - - if (*pGroupMembersBufferIsMalloced == 0) - { - memcpy (*pGroupMembers, groupMembers, i * sizeof (char *)); - groupMembers = NULL; /* defensive programming */ - *pGroupMembersBufferIsMalloced = 1; - } - } - - groupMembers = *pGroupMembers; - - /* Parse distinguished name members */ - if (dnValues != NULL) - { - for (valiter = dnValues; *valiter != NULL; valiter++) - { - LDAPMessage *res; - enum nss_status parseStat; - int isNestedGroup = 0; - char *uid; - - uid = strrchr (*valiter, '#'); - if (uid != NULL) - { - *uid = '\0'; - } - - parseStat = _nss_ldap_dn2uid (*valiter, &groupMembers[i], - buffer, buflen, &isNestedGroup, - &res); - if (parseStat == NSS_STATUS_SUCCESS) - { - if (isNestedGroup == 0) - { - /* just a normal user which we have flattened */ - i++; - continue; - } - - (*depth)++; - parseStat = - do_parse_group_members (_nss_ldap_first_entry (res), - &groupMembers, &i, - pGroupMembersBufferSize, - pGroupMembersBufferIsMalloced, - buffer, buflen, depth, - pKnownGroups); - (*depth)--; - - if (parseStat == NSS_STATUS_TRYAGAIN) - { - stat = NSS_STATUS_TRYAGAIN; - goto out; - } - - ldap_msgfree (res); - } - else if (parseStat == NSS_STATUS_TRYAGAIN) - { - stat = NSS_STATUS_TRYAGAIN; - goto out; - } - } - } - - /* Parse RFC 2307 (flat) members */ - if (uidValues != NULL) - { - for (valiter = uidValues; *valiter != NULL; valiter++) - { - size_t len = strlen (*valiter) + 1; - if (*buflen < len) - { - stat = NSS_STATUS_TRYAGAIN; - goto out; - } - groupMembers[i] = *buffer; - *buffer += len; - *buflen -= len; - - memcpy (groupMembers[i++], *valiter, len); - } - } - - /* Get next range for Active Directory compat */ - if (end != -1) - { - stat = do_construct_range_attribute (uniquemember_attr, - end + 1, - -1, - buffer, - buflen, - &uniquemember_attrs[0]); - if (stat == NSS_STATUS_SUCCESS) - { - if (dnValues != NULL) - { - ldap_value_free (dnValues); - dnValues = NULL; - } - if (uidValues != NULL) - { - ldap_value_free (uidValues); - uidValues = NULL; - } - if (res != NULL) - { - ldap_msgfree (res); - res = NULL; - } - - stat = _nss_ldap_read (groupdn, uniquemember_attrs, &res); - if (stat != NSS_STATUS_SUCCESS) - goto out; - - e = _nss_ldap_first_entry (res); - } - } - } - while (end != -1); - -out: - if (dnValues != NULL) - ldap_value_free (dnValues); - if (uidValues != NULL) - ldap_value_free (uidValues); - if (res != NULL) - ldap_msgfree (res); - if (groupdn != NULL) -#ifdef HAVE_LDAP_MEMFREE - ldap_memfree (groupdn); -#else - free (groupdn); -#endif - - *pGroupMembers = groupMembers; - *pGroupMembersCount = i; - - return stat; -} - -/* - * "Fix" group membership list into caller provided buffer, - * and NULL terminate. -*/ -static enum nss_status -do_fix_group_members_buffer (char **mallocedGroupMembers, - size_t groupMembersCount, - char ***pGroupMembers, - char **buffer, size_t * buflen) -{ - size_t len; - - len = (groupMembersCount + 1) * sizeof (char *); - - if (bytesleft (*buffer, *buflen, char *) < len) - { - return NSS_STATUS_TRYAGAIN; - } - - align (*buffer, *buflen, char *); - *pGroupMembers = (char **) *buffer; - *buffer += len; - *buflen -= len; - - memcpy (*pGroupMembers, mallocedGroupMembers, - groupMembersCount * sizeof (char *)); - (*pGroupMembers)[groupMembersCount] = NULL; - - return NSS_STATUS_SUCCESS; -} - -static enum nss_status -_nss_ldap_parse_gr (LDAPMessage * e, - struct ldap_state * pvt, - void *result, char *buffer, size_t buflen) -{ - struct group *gr = (struct group *) result; - char *gid; - enum nss_status stat; - char **groupMembers; - size_t groupMembersCount; - size_t groupMembersBufferSize; - char *groupMembersBuffer[LDAP_NSS_NGROUPS]; - int groupMembersBufferIsMalloced; - int depth; - struct name_list *knownGroups = NULL; - - stat = - _nss_ldap_assign_attrval (e, ATM (LM_GROUP, gidNumber), &gid, &buffer, - &buflen); - if (stat != NSS_STATUS_SUCCESS) - return stat; - - gr->gr_gid = - (*gid == '\0') ? (unsigned) GID_NOBODY : (gid_t) strtoul (gid, - (char **) NULL, - 10); - - stat = - _nss_ldap_getrdnvalue (e, ATM (LM_GROUP, cn), &gr->gr_name, &buffer, - &buflen); - if (stat != NSS_STATUS_SUCCESS) - return stat; - - stat = - _nss_ldap_assign_userpassword (e, ATM (LM_GROUP, userPassword), - &gr->gr_passwd, &buffer, &buflen); - if (stat != NSS_STATUS_SUCCESS) - return stat; - - if (_nss_ldap_test_config_flag (NSS_LDAP_FLAGS_RFC2307BIS)) - { - groupMembers = groupMembersBuffer; - groupMembersCount = 0; - groupMembersBufferSize = sizeof (groupMembers); - groupMembersBufferIsMalloced = 0; - depth = 0; - - stat = do_parse_group_members (e, &groupMembers, &groupMembersCount, - &groupMembersBufferSize, - &groupMembersBufferIsMalloced, &buffer, - &buflen, &depth, &knownGroups); - if (stat != NSS_STATUS_SUCCESS) - { - if (groupMembersBufferIsMalloced) - free (groupMembers); - _nss_ldap_namelist_destroy (&knownGroups); - return stat; - } - - stat = do_fix_group_members_buffer (groupMembers, groupMembersCount, - &gr->gr_mem, &buffer, &buflen); - - if (groupMembersBufferIsMalloced) - free (groupMembers); - _nss_ldap_namelist_destroy (&knownGroups); - } - else - { - stat = - _nss_ldap_assign_attrvals (e, ATM (LM_GROUP, memberUid), NULL, - &gr->gr_mem, &buffer, &buflen, NULL); - } - - return stat; -} - -/* - * Add a group ID to a group list, and optionally the group IDs - * of any groups to which this group belongs (RFC2307bis nested - * group expansion is done by do_parse_initgroups_nested()). - */ -static enum nss_status -do_parse_initgroups (LDAPMessage * e, - struct ldap_state * pvt, void *result, - char *buffer, size_t buflen) -{ - char **values; - ssize_t i; - gid_t gid; - ldap_initgroups_args_t *lia = (ldap_initgroups_args_t *) result; - - values = _nss_ldap_get_values (e, ATM (LM_GROUP, gidNumber)); - if (values == NULL) - { - /* invalid group; skip it */ - return NSS_STATUS_NOTFOUND; - } - - if (values[0] == NULL) - { - /* invalid group; skip it */ - ldap_value_free (values); - return NSS_STATUS_NOTFOUND; - } - -#ifdef HAVE_USERSEC_H - i = strlen (values[0]); - lia->grplist = realloc (lia->grplist, lia->listlen + i + 2); - if (lia->grplist == NULL) - { - ldap_value_free (values); - return NSS_STATUS_TRYAGAIN; - } - memcpy (lia->grplist + lia->listlen, values[0], i); - lia->grplist[lia->listlen + i] = ','; - lia->listlen += i + 1; - ldap_value_free (values); -#else - gid = strtoul (values[0], (char **) NULL, 10); - ldap_value_free (values); - - if (gid == LONG_MAX && errno == ERANGE) - { - /* invalid group, skip it */ - return NSS_STATUS_NOTFOUND; - } - - if (gid == lia->group) - { - /* primary group, so skip it */ - return NSS_STATUS_NOTFOUND; - } - - if (lia->limit > 0) - { - if (*(lia->start) >= lia->limit) - { - /* can't fit any more */ - return NSS_STATUS_TRYAGAIN; - } - } - if (*(lia->start) == *(lia->size)) - { - /* Need a bigger buffer */ - *(lia->groups) = (gid_t *) realloc (*(lia->groups), - 2 * *(lia->size) * sizeof (gid_t)); - if (*(lia->groups) == NULL) - { - return NSS_STATUS_TRYAGAIN; - } - *(lia->size) *= 2; - } - - /* weed out duplicates; is this really our responsibility? */ - for (i = 0; i < *(lia->start); i++) - { - if ((*(lia->groups))[i] == gid) - { - return NSS_STATUS_NOTFOUND; - } - } - - /* add to group list */ - (*(lia->groups))[*(lia->start)] = gid; - (*(lia->start)) += 1; -#endif /* HAVE_USERSEC_H */ - - return NSS_STATUS_NOTFOUND; -} - -static enum nss_status -do_parse_initgroups_nested (LDAPMessage * e, - struct ldap_state * pvt, void *result, - char *buffer, size_t buflen) -{ - enum nss_status status; - ldap_initgroups_args_t *lia = (ldap_initgroups_args_t *) result; - char **values; - char *groupdn; - - status = do_parse_initgroups (e, pvt, result, buffer, buflen); - if (status != NSS_STATUS_NOTFOUND) - { - return status; - } - - if (!_nss_ldap_test_config_flag (NSS_LDAP_FLAGS_RFC2307BIS)) - { - return NSS_STATUS_NOTFOUND; - } - - if (lia->backlink != 0) - { - /* - * Now add the GIDs of any groups of which this group is - * a member. - */ - values = _nss_ldap_get_values (e, ATM (LM_GROUP, memberOf)); - if (values != NULL) - { - lia->depth++; - status = ng_chase_backlink ((const char **)values, lia); - lia->depth--; - - ldap_value_free (values); - - return status; - } - } - else - { - /* - * Now add the GIDs of any groups which refer to this group - */ - groupdn = _nss_ldap_get_dn (e); - if (groupdn != NULL) - { - /* Note: there was a problem here with stat in the orriginal code */ - lia->depth++; - status = ng_chase (groupdn, lia); - lia->depth--; -#ifdef HAVE_LDAP_MEMFREE - ldap_memfree (groupdn); -#else - free (groupdn); -#endif - } - } - - return status; -} - -static enum nss_status ng_chase(const char *dn, ldap_initgroups_args_t * lia) -{ - struct ldap_args a; - enum nss_status stat; - struct ent_context *ctx=NULL; - const char *gidnumber_attrs[2]; - int erange; - - if (lia->depth > LDAP_NSS_MAXGR_DEPTH) - return NSS_STATUS_NOTFOUND; - - if (_nss_ldap_namelist_find (lia->known_groups, dn)) - return NSS_STATUS_NOTFOUND; - - gidnumber_attrs[0] = ATM (LM_GROUP, gidNumber); - gidnumber_attrs[1] = NULL; - - LA_INIT (a); - LA_STRING (a) = dn; - LA_TYPE (a) = LA_TYPE_STRING; - - if (_nss_ldap_ent_context_init_locked (&ctx) == NULL) - { - return NSS_STATUS_UNAVAIL; - } - - stat = _nss_ldap_getent_ex (&a, &ctx, lia, NULL, 0, - &erange, _nss_ldap_filt_getgroupsbydn, - LM_GROUP, gidnumber_attrs, - do_parse_initgroups_nested); - - if (stat == NSS_STATUS_SUCCESS) - { - stat = _nss_ldap_namelist_push (&lia->known_groups, dn); - } - - _nss_ldap_ent_context_release (ctx); - free (ctx); - - return stat; -} - -static enum nss_status ng_chase_backlink(const char ** membersOf, ldap_initgroups_args_t * lia) -{ - struct ldap_args a; - enum nss_status stat; - struct ent_context *ctx=NULL; - const char *gidnumber_attrs[3]; - const char **memberP; - const char **filteredMembersOf; /* remove already traversed groups */ - size_t memberCount, i; - int erange; - - if (lia->depth > LDAP_NSS_MAXGR_DEPTH) - return NSS_STATUS_NOTFOUND; - - for (memberCount = 0; membersOf[memberCount] != NULL; memberCount++) - ; - - /* Build a list of membersOf values without any already traversed groups */ - filteredMembersOf = (const char **) malloc(sizeof(char *) * (memberCount + 1)); - if (filteredMembersOf == NULL) - { - return NSS_STATUS_TRYAGAIN; - } - - memberP = filteredMembersOf; - - for (i = 0; i < memberCount; i++) - { - if (_nss_ldap_namelist_find (lia->known_groups, membersOf[i])) - continue; - - *memberP = membersOf[i]; - memberP++; - } - - *memberP = NULL; - - if (filteredMembersOf[0] == NULL) - { - free (filteredMembersOf); - return NSS_STATUS_NOTFOUND; - } - - gidnumber_attrs[0] = ATM (LM_GROUP, gidNumber); - gidnumber_attrs[1] = ATM (LM_GROUP, memberOf); - gidnumber_attrs[2] = NULL; - - LA_INIT (a); - LA_STRING_LIST (a) = filteredMembersOf; - LA_TYPE (a) = LA_TYPE_STRING_LIST_OR; - - if (_nss_ldap_ent_context_init_locked (&ctx) == NULL) - { - free (filteredMembersOf); - return NSS_STATUS_UNAVAIL; - } - - stat = _nss_ldap_getent_ex (&a, &ctx, lia, NULL, 0, - &erange, "(distinguishedName=%s)", - LM_GROUP, gidnumber_attrs, - do_parse_initgroups_nested); - - if (stat == NSS_STATUS_SUCCESS) - { - enum nss_status stat2; - - for (memberP = filteredMembersOf; *memberP != NULL; memberP++) - { - stat2 = _nss_ldap_namelist_push (&lia->known_groups, *memberP); - if (stat2 != NSS_STATUS_SUCCESS) - { - stat = stat2; - break; - } - } - } - - free (filteredMembersOf); - - _nss_ldap_ent_context_release (ctx); - free (ctx); - - return stat; -} - - -static enum nss_status group_bymember(const char *user, long int *start, - long int *size, long int limit, - int *errnop) -{ - ldap_initgroups_args_t lia; - int erange = 0; - char *userdn = NULL; - LDAPMessage *res, *e; - static const char *no_attrs[] = { NULL }; - const char *filter; - struct ldap_args a; - enum nss_status stat; - struct ent_context *ctx=NULL; - const char *gidnumber_attrs[3]; - enum ldap_map_selector map = LM_GROUP; - - LA_INIT (a); - LA_STRING (a) = user; - LA_TYPE (a) = LA_TYPE_STRING; - - debug ("==> group_bymember (user=%s)", LA_STRING (a) ); - - lia.depth = 0; - lia.known_groups = NULL; - - _nss_ldap_enter (); - - /* initialize schema */ - stat = _nss_ldap_init (); - if (stat != NSS_STATUS_SUCCESS) - { - debug ("<== group_bymember (init failed)"); - _nss_ldap_leave (); - return stat; - } - - if (_nss_ldap_test_initgroups_ignoreuser (LA_STRING (a))) - { - debug ("<== group_bymember (user ignored)"); - _nss_ldap_leave (); - return NSS_STATUS_NOTFOUND; - } - - lia.backlink = _nss_ldap_test_config_flag (NSS_LDAP_FLAGS_INITGROUPS_BACKLINK); - - if (lia.backlink != 0) - { - filter = _nss_ldap_filt_getpwnam_groupsbymember; - LA_STRING2 (a) = LA_STRING (a); - LA_TYPE (a) = LA_TYPE_STRING_AND_STRING; - - gidnumber_attrs[0] = ATM (LM_GROUP, gidNumber); - gidnumber_attrs[1] = ATM (LM_GROUP, memberOf); - gidnumber_attrs[2] = NULL; - - map = LM_PASSWD; - } - else - { - if (_nss_ldap_test_config_flag (NSS_LDAP_FLAGS_RFC2307BIS)) - { - /* lookup the user's DN. */ - stat = _nss_ldap_search_s (&a, _nss_ldap_filt_getpwnam, LM_PASSWD, - no_attrs, 1, &res); - if (stat == NSS_STATUS_SUCCESS) - { - e = _nss_ldap_first_entry (res); - if (e != NULL) - { - userdn = _nss_ldap_get_dn (e); - } - ldap_msgfree (res); - } - } - else - { - userdn = NULL; - } - - if (userdn != NULL) - { - LA_STRING2 (a) = userdn; - LA_TYPE (a) = LA_TYPE_STRING_AND_STRING; - filter = _nss_ldap_filt_getgroupsbymemberanddn; - } - else - { - filter = _nss_ldap_filt_getgroupsbymember; - } - - gidnumber_attrs[0] = ATM (LM_GROUP, gidNumber); - gidnumber_attrs[1] = NULL; - } - - if (_nss_ldap_ent_context_init_locked(&ctx)==NULL) - { - debug ("<== group_bymember (ent_context_init failed)"); - _nss_ldap_leave (); - return NSS_STATUS_UNAVAIL; - } - - stat = _nss_ldap_getent_ex (&a, &ctx, (void *) &lia, NULL, 0, - errnop, - filter, - map, - gidnumber_attrs, - do_parse_initgroups_nested); - - if (userdn != NULL) - ldap_memfree (userdn); - - _nss_ldap_namelist_destroy (&lia.known_groups); - _nss_ldap_ent_context_release (ctx); - free (ctx); - _nss_ldap_leave (); - - /* - * We return NSS_STATUS_NOTFOUND to force the parser to be called - * for as many entries (i.e. groups) as exist, for all - * search descriptors. So confusingly this means "success". - */ - if (stat != NSS_STATUS_SUCCESS && stat != NSS_STATUS_NOTFOUND) - { - debug ("<== group_bymember (not found)"); - if (erange) - errno = ERANGE; - return stat; - } - - debug ("<== group_bymember (success)"); - - return NSS_STATUS_SUCCESS; -} - -/* macros for expanding the NSLCD_GROUP macro */ -#define NSLCD_STRING(field) WRITE_STRING(fp,field) -#define NSLCD_TYPE(field,type) WRITE_TYPE(fp,field,type) -#define NSLCD_STRINGLIST(field) WRITE_STRINGLIST_NULLTERM(fp,field) -#define GROUP_NAME result.gr_name -#define GROUP_PASSWD result.gr_passwd -#define GROUP_GID result.gr_gid -#define GROUP_MEMBERS result.gr_mem - -int nslcd_group_byname(FILE *fp) -{ - int32_t tmpint32,tmp2int32,tmp3int32; - char *name; - struct ldap_args a; - /* these are here for now until we rewrite the LDAP code */ - struct group result; - char buffer[1024]; - int errnop; - int retv; - /* read request parameters */ - READ_STRING_ALLOC(fp,name); - /* FIXME: free() this buffer somewhere */ - /* log call */ - log_log(LOG_DEBUG,"nslcd_group_byname(%s)",name); - /* static buffer size check */ - if (1024<LDAP_NSS_BUFLEN_GROUP) - { - log_log(LOG_CRIT,"allocated buffer in nslcd_group_byname() too small"); - exit(1); - } - /* do the LDAP request */ - LA_INIT(a); - LA_STRING(a)=name; - LA_TYPE(a)=LA_TYPE_STRING; - retv=nss2nslcd(_nss_ldap_getbyname(&a,&result,buffer,1024,&errnop,_nss_ldap_filt_getgrnam,LM_GROUP,_nss_ldap_parse_gr)); - /* no more need for this */ - free(name); - /* write the response */ - WRITE_INT32(fp,NSLCD_VERSION); - WRITE_INT32(fp,NSLCD_ACTION_GROUP_BYNAME); - WRITE_INT32(fp,retv); - if (retv==NSLCD_RESULT_SUCCESS) - { - NSLCD_GROUP; - } - WRITE_FLUSH(fp); - /* we're done */ - return 0; -} - -int nslcd_group_bygid(FILE *fp) -{ - int32_t tmpint32,tmp2int32,tmp3int32; - gid_t gid; - struct ldap_args a; - /* these are here for now until we rewrite the LDAP code */ - struct group result; - char buffer[1024]; - int errnop; - int retv; - /* read request parameters */ - READ_TYPE(fp,gid,gid_t); - /* FIXME: free() this buffer somewhere */ - /* log call */ - log_log(LOG_DEBUG,"nslcd_group_bygid(%d)",(int)gid); - /* static buffer size check */ - if (1024<LDAP_NSS_BUFLEN_GROUP) - { - log_log(LOG_CRIT,"allocated buffer in nslcd_group_byname() too small"); - exit(1); - } - /* do the LDAP request */ - LA_INIT(a); - LA_NUMBER(a)=gid; - LA_TYPE(a)=LA_TYPE_NUMBER; - retv=nss2nslcd(_nss_ldap_getbyname(&a,&result,buffer,1024,&errnop,_nss_ldap_filt_getgrgid,LM_GROUP,_nss_ldap_parse_gr)); - /* write the response */ - WRITE_INT32(fp,NSLCD_VERSION); - WRITE_INT32(fp,NSLCD_ACTION_GROUP_BYGID); - WRITE_INT32(fp,retv); - if (retv==NSLCD_RESULT_SUCCESS) - { - NSLCD_GROUP; - } - WRITE_FLUSH(fp); - /* we're done */ - return 0; -} - -int nslcd_group_bymember(FILE *fp) -{ - int32_t tmpint32; - char *name; - /* these are here for now until we rewrite the LDAP code */ - int errnop; - int retv; - long int start=0,size=1024; - long int i; - gid_t groupsp[1024]; - /* read request parameters */ - READ_STRING_ALLOC(fp,name); - /* FIXME: free() this buffer somewhere */ - /* log call */ - log_log(LOG_DEBUG,"nslcd_group_bymember(%s)",name); - /* do the LDAP request */ - retv=NSLCD_RESULT_NOTFOUND; - /* - retv=nss2nslcd(group_bymember(name,&start,&size,size,&errnop)); - */ - /* Note: we write some garbadge here to ensure protocol error as this - function currently returns incorrect data */ - /* Note: what to do with group ids that are not listed as supplemental - groups but are the user's primary group id? */ - WRITE_INT32(fp,1234); - start=0; - /* TODO: fix this to actually work */ - /* write the response header */ - WRITE_INT32(fp,NSLCD_VERSION); - WRITE_INT32(fp,NSLCD_ACTION_GROUP_BYNAME); - if (retv==NSLCD_RESULT_SUCCESS) - { - /* loop over the returned gids */ - for (i=0;i<start;i++) - { - WRITE_INT32(fp,NSLCD_RESULT_SUCCESS); - /* Note: we will write a fake record here for now. This is because - we want to keep the protocol but currently the only - client application available discards non-gid information */ - WRITE_STRING(fp,""); /* group name */ - WRITE_STRING(fp,"*"); /* group passwd */ - WRITE_TYPE(fp,groupsp[i],gid_t); /* gid */ - WRITE_INT32(fp,1); /* number of members */ - WRITE_STRING(fp,name); /* member=user requested */ - } - WRITE_INT32(fp,NSLCD_RESULT_NOTFOUND); - } - else - { - /* some error occurred */ - WRITE_INT32(fp,retv); - } - WRITE_FLUSH(fp); - /* no more need for this */ - free(name); - /* we're done */ - return 0; -} - -int nslcd_group_all(FILE *fp) -{ - int32_t tmpint32,tmp2int32,tmp3int32; - struct ent_context *gr_context=NULL; - /* these are here for now until we rewrite the LDAP code */ - struct group result; - char buffer[1024]; - int errnop; - int retv; - /* log call */ - log_log(LOG_DEBUG,"nslcd_group_all()"); - /* write the response header */ - WRITE_INT32(fp,NSLCD_VERSION); - WRITE_INT32(fp,NSLCD_ACTION_GROUP_ALL); - /* initialize context */ - if (_nss_ldap_ent_context_init(&gr_context)==NULL) - return -1; - /* loop over all results */ - while ((retv=nss2nslcd(_nss_ldap_getent(&gr_context,&result,buffer,1024,&errnop,_nss_ldap_filt_getgrent,LM_GROUP,_nss_ldap_parse_gr)))==NSLCD_RESULT_SUCCESS) - { - /* write the result */ - WRITE_INT32(fp,retv); - NSLCD_GROUP; - } - /* write the final result code */ - WRITE_INT32(fp,retv); - WRITE_FLUSH(fp); - /* FIXME: if a previous call returns what happens to the context? */ - _nss_ldap_enter(); - _nss_ldap_ent_context_release(gr_context); - _nss_ldap_leave(); - /* we're done */ - return 0; -} diff --git a/server/host.c b/server/host.c deleted file mode 100644 index ec04bf2..0000000 --- a/server/host.c +++ /dev/null @@ -1,380 +0,0 @@ -/* - host.c - host name lookup routines - This file was part of the nss_ldap library (as ldap-hosts.c) - which has been forked into the nss-ldapd library. - - Copyright (C) 1997-2005 Luke Howard - Copyright (C) 2006 West Consulting - Copyright (C) 2006 Arthur de Jong - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1301 USA -*/ - -#include "config.h" - -#include <sys/socket.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <netdb.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <arpa/nameser.h> -#include <resolv.h> -#ifdef HAVE_LBER_H -#include <lber.h> -#endif -#ifdef HAVE_LDAP_H -#include <ldap.h> -#endif -#if defined(HAVE_THREAD_H) -#include <thread.h> -#elif defined(HAVE_PTHREAD_H) -#include <pthread.h> -#endif -#ifdef INET6 -#include <resolv/mapv4v6addr.h> -#endif - -#include "ldap-nss.h" -#include "util.h" -#include "common.h" -#include "log.h" - -#ifndef MAXALIASES -#define MAXALIASES 35 -#endif - -/* write a single host entry to the stream */ -static int write_hostent(FILE *fp,struct hostent *result) -{ - int32_t tmpint32,tmp2int32,tmp3int32; - int numaddr,i; - /* write the host entry */ - WRITE_STRING(fp,result->h_name); - /* write the alias list */ - WRITE_STRINGLIST_NULLTERM(fp,result->h_aliases); - /* write the number of addresses */ - for (numaddr=0;result->h_addr_list[numaddr]!=NULL;numaddr++) - /*noting*/ ; - WRITE_INT32(fp,numaddr); - /* write the addresses */ - for (i=0;i<numaddr;i++) - { - WRITE_INT32(fp,result->h_addrtype); - WRITE_INT32(fp,result->h_length); - WRITE(fp,result->h_addr_list[i],result->h_length); - } - return 0; -} - -static enum nss_status -_nss_ldap_parse_host (LDAPMessage * e, - struct ldap_state * pvt, - void *result, char *buffer, size_t buflen, - int af) -{ - /* this code needs reviewing. XXX */ - struct hostent *host = (struct hostent *) result; - enum nss_status stat; -#ifdef INET6 - char addressbuf[sizeof ("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255") * - MAXALIASES]; -#else - char addressbuf[sizeof ("255.255.255.255") * MAXALIASES]; -#endif - char *p_addressbuf = addressbuf; - char **addresses = NULL; - size_t addresslen = sizeof (addressbuf); - size_t addresscount = 0; - char **host_addresses = NULL; - int i; - - *addressbuf = *buffer = '\0'; - - stat = _nss_ldap_assign_attrval (e, ATM (LM_HOSTS, cn), &host->h_name, - &buffer, &buflen); - if (stat != NSS_STATUS_SUCCESS) - return stat; - - stat = - _nss_ldap_assign_attrvals (e, ATM (LM_HOSTS, cn), host->h_name, - &host->h_aliases, &buffer, &buflen, NULL); - if (stat != NSS_STATUS_SUCCESS) - return stat; - - stat = - _nss_ldap_assign_attrvals (e, AT (ipHostNumber), NULL, &addresses, - &p_addressbuf, &addresslen, &addresscount); - if (stat != NSS_STATUS_SUCCESS) - return stat; - if (addresscount == 0) - return NSS_STATUS_NOTFOUND; - -#ifdef INET6 - if (af == AF_INET6) - { - if (bytesleft (buffer, buflen, char *) < - (size_t) ((addresscount + 1) * IN6ADDRSZ)) - return NSS_STATUS_TRYAGAIN; - } - else - { - if (bytesleft (buffer, buflen, char *) < - (size_t) ((addresscount + 1) * INADDRSZ)) - return NSS_STATUS_TRYAGAIN; - } -#else - if (bytesleft (buffer, buflen, char *) < - (size_t) ((addresscount + 1) * INADDRSZ)) - return NSS_STATUS_TRYAGAIN; -#endif - - align (buffer, buflen, char *); - host_addresses = (char **) buffer; - host->h_addr_list = host_addresses; - host_addresses[addresscount] = NULL; - - buffer += (addresscount + 1) * sizeof (char *); - buflen -= (addresscount + 1) * sizeof (char *); -#ifdef INET6 - host->h_addrtype = 0; - host->h_length = 0; -#else - host->h_addrtype = AF_INET; - host->h_length = INADDRSZ; -#endif - - for (i = 0; i < (int) addresscount; i++) - { -#ifdef INET6 - char *addr = addresses[i]; - char entdata[16]; - /* from glibc NIS parser. Thanks, Uli. */ - - if (af == AF_INET && inet_pton (AF_INET, addr, entdata) > 0) - { - if (_res.options & RES_USE_INET6) - { - map_v4v6_address ((char *) entdata, - (char *) entdata); - host->h_addrtype = AF_INET6; - host->h_length = IN6ADDRSZ; - } - else - { - host->h_addrtype = AF_INET; - host->h_length = INADDRSZ; - } - } - else if (af == AF_INET6 - && inet_pton (AF_INET6, addr, entdata) > 0) - { - host->h_addrtype = AF_INET6; - host->h_length = IN6ADDRSZ; - } - else - /* Illegal address: ignore line. */ - continue; - -#else - unsigned long haddr; - haddr = inet_addr (addresses[i]); -#endif - - if (buflen < (size_t) host->h_length) - return NSS_STATUS_TRYAGAIN; - -#ifdef INET6 - memcpy (buffer, entdata, host->h_length); - *host_addresses = buffer; - buffer += host->h_length; - buflen -= host->h_length; -#else - memcpy (buffer, &haddr, INADDRSZ); - *host_addresses = buffer; - buffer += INADDRSZ; - buflen -= INADDRSZ; -#endif - - host_addresses++; - *host_addresses = NULL; - } - -#ifdef INET6 - /* if host->h_addrtype is not changed, this entry does not - have the right IP address. */ - if (host->h_addrtype == 0) - return NSS_STATUS_NOTFOUND; -#endif - - return NSS_STATUS_SUCCESS; -} - -static enum nss_status -_nss_ldap_parse_hostv4 (LDAPMessage * e, - struct ldap_state * pvt, - void *result, char *buffer, size_t buflen) -{ - return _nss_ldap_parse_host (e, pvt, result, buffer, buflen, - AF_INET); -} - -#ifdef INET6 -static enum nss_status -_nss_ldap_parse_hostv6 (LDAPMessage * e, - struct ldap_state * pvt, - void *result, char *buffer, size_t buflen) -{ - return _nss_ldap_parse_host (e, pvt, result, buffer, buflen, - AF_INET6); -} -#endif - -int nslcd_host_byname(FILE *fp) -{ - int32_t tmpint32; - char *name; - struct ldap_args a; - int retv; - struct hostent result; - char buffer[1024]; - int errnop; - /* read request parameters */ - READ_STRING_ALLOC(fp,name); - /* log call */ - log_log(LOG_DEBUG,"nslcd_host_byname(%s)",name); - /* write the response header */ - WRITE_INT32(fp,NSLCD_VERSION); - WRITE_INT32(fp,NSLCD_ACTION_HOST_BYNAME); - /* do the LDAP request */ - LA_INIT(a); - LA_STRING(a)=name; - LA_TYPE(a)=LA_TYPE_STRING; - retv=nss2nslcd(_nss_ldap_getbyname(&a,&result,buffer,1024,&errnop,_nss_ldap_filt_gethostbyname,LM_HOSTS, -#ifdef INET6 - (af == AF_INET6)?_nss_ldap_parse_hostv6:_nss_ldap_parse_hostv4)); -#else - _nss_ldap_parse_hostv4)); -#endif - /* no more need for this string */ - free(name); - /* write the response */ - WRITE_INT32(fp,retv); - if (retv==NSLCD_RESULT_SUCCESS) - write_hostent(fp,&result); - WRITE_FLUSH(fp); - /* we're done */ - return 0; -} - -int nslcd_host_byaddr(FILE *fp) -{ - int32_t tmpint32; - int af; - int len; - char addr[64],name[1024]; - struct ldap_args a; - int retv; - struct hostent result; - char buffer[1024]; - int errnop; - /* read address family */ - READ_INT32(fp,af); - if ((af!=AF_INET)&&(af!=AF_INET6)) - { - log_log(LOG_WARNING,"incorrect address family specified: %d",af); - return -1; - } - /* read address length */ - READ_INT32(fp,len); - if ((len>64)||(len<=0)) - { - log_log(LOG_WARNING,"address length incorrect: %d",len); - return -1; - } - /* read address */ - READ(fp,addr,len); - /* translate the address to a string */ - if (inet_ntop(af,addr,name,1024)==NULL) - { - log_log(LOG_WARNING,"unable to convert address to string"); - return -1; - } - /* log call */ - log_log(LOG_DEBUG,"nslcd_host_byaddr(%s)",name); - /* write the response header */ - WRITE_INT32(fp,NSLCD_VERSION); - WRITE_INT32(fp,NSLCD_ACTION_HOST_BYADDR); - /* do the LDAP request */ - LA_INIT(a); - LA_STRING(a)=name; - LA_TYPE(a)=LA_TYPE_STRING; - retv=nss2nslcd(_nss_ldap_getbyname(&a,&result,buffer,1024,&errnop,_nss_ldap_filt_gethostbyaddr,LM_HOSTS, -#ifdef INET6 - (af == AF_INET6)?_nss_ldap_parse_hostv6:_nss_ldap_parse_hostv4)); -#else - _nss_ldap_parse_hostv4)); -#endif - /* write the response */ - WRITE_INT32(fp,retv); - if (retv==NSLCD_RESULT_SUCCESS) - write_hostent(fp,&result); - WRITE_FLUSH(fp); - /* we're done */ - return 0; -} - -int nslcd_host_all(FILE *fp) -{ - int32_t tmpint32; - static struct ent_context *host_context; - /* these are here for now until we rewrite the LDAP code */ - struct hostent result; - char buffer[1024]; - int errnop; - int retv; - /* log call */ - log_log(LOG_DEBUG,"nslcd_host_all()"); - /* write the response header */ - WRITE_INT32(fp,NSLCD_VERSION); - WRITE_INT32(fp,NSLCD_ACTION_HOST_ALL); - /* initialize context */ - if (_nss_ldap_ent_context_init(&host_context)==NULL) - return -1; - /* loop over all results */ - while ((retv=nss2nslcd(_nss_ldap_getent(&host_context,&result,buffer,1024,&errnop,_nss_ldap_filt_gethostent,LM_HOSTS, -#ifdef INET6 - (_res.options&RES_USE_INET6)?_nss_ldap_parse_hostv6:_nss_ldap_parse_hostv4 -#else - _nss_ldap_parse_hostv4 -#endif - )))==NSLCD_RESULT_SUCCESS) - { - /* write the result */ - WRITE_INT32(fp,retv); - write_hostent(fp,&result); - } - /* write the final result code */ - WRITE_INT32(fp,retv); - WRITE_FLUSH(fp); - /* FIXME: if a previous call returns what happens to the context? */ - _nss_ldap_enter(); - _nss_ldap_ent_context_release(host_context); - _nss_ldap_leave(); - /* we're done */ - return 0; -} diff --git a/server/ldap-nss.c b/server/ldap-nss.c deleted file mode 100644 index f442037..0000000 --- a/server/ldap-nss.c +++ /dev/null @@ -1,4032 +0,0 @@ -/* - ldap-nss.c - main file for NSS interface - This file was part of the nss_ldap library which has been - forked into the nss-ldapd library. - - Copyright (C) 1997-2006 Luke Howard - Copyright (C) 2006 West Consulting - Copyright (C) 2006 Arthur de Jong - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1301 USA -*/ - -#include "config.h" - -#include <assert.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#ifdef HAVE_STRINGS_H -#include <strings.h> -#endif -#include <stdio.h> -#include <syslog.h> -#include <signal.h> -#include <fcntl.h> -#include <sys/time.h> -#include <sys/socket.h> -#include <sys/param.h> -#include <errno.h> -#ifdef HAVE_SYS_UN_H -#include <sys/un.h> -#endif -#include <netinet/in.h> -#ifdef HAVE_LBER_H -#include <lber.h> -#endif -#ifdef HAVE_LDAP_H -#include <ldap.h> -#endif -#ifdef HAVE_LDAP_SSL_H -#include <ldap_ssl.h> -#endif -#ifdef HAVE_GSSLDAP_H -#include <gssldap.h> -#endif -#ifdef HAVE_GSSSASL_H -#include <gsssasl.h> -#endif -#ifdef HAVE_MALLOC_H -#include <malloc.h> -#endif -#if defined(HAVE_THREAD_H) -#include <thread.h> -#elif defined(HAVE_PTHREAD_H) -#include <pthread.h> -#endif -/* Try to handle systems with both SASL libraries installed */ -#if defined(HAVE_SASL_SASL_H) && defined(HAVE_SASL_AUXPROP_REQUEST) -#include <sasl/sasl.h> -#elif defined(HAVE_SASL_H) -#include <sasl.h> -#endif -#ifdef HAVE_GSSAPI_H -#include <gssapi.h> -#elif defined(HAVE_GSSAPI_GSSAPI_KRB5_H) -#include <gssapi/gssapi.h> -#include <gssapi/gssapi_krb5.h> -#endif - -#include "ldap-nss.h" -#include "util.h" -#include "dnsconfig.h" -#include "pagectrl.h" -#include "common.h" -#include "log.h" - -#if defined(HAVE_THREAD_H) -#ifdef HAVE_PTHREAD_ATFORK -#undef HAVE_PTHREAD_ATFORK -#endif -#endif - -/* how many messages to retrieve results for */ -#ifndef LDAP_MSG_ONE -#define LDAP_MSG_ONE 0x00 -#endif -#ifndef LDAP_MSG_ALL -#define LDAP_MSG_ALL 0x01 -#endif -#ifndef LDAP_MSG_RECEIVED -#define LDAP_MSG_RECEIVED 0x02 -#endif - -#ifdef HAVE_LDAP_LD_FREE -#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) -extern int ldap_ld_free (LDAP * ld, int close, LDAPControl **, - LDAPControl **); -#else -extern int ldap_ld_free (LDAP * ld, int close); -#endif /* OPENLDAP 2.x */ -#endif /* HAVE_LDAP_LD_FREE */ - -NSS_LDAP_DEFINE_LOCK (__lock); - -/* - * LS_INIT only used for enumeration contexts - */ -#define LS_INIT(state) do { state.ls_type = LS_TYPE_INDEX; state.ls_retry = 0; state.ls_info.ls_index = -1; } while (0) - -/* - * the configuration is read by the first call to do_open(). - * Pointers to elements of the list are passed around but should not - * be freed. - */ -static char __configbuf[NSS_LDAP_CONFIG_BUFSIZ]; -static struct ldap_config *__config = NULL; - -#ifdef HAVE_SIGACTION -static struct sigaction __stored_handler; -static int __sigaction_retval = -1; -#else -static void (*__sigpipe_handler) (int) = SIG_DFL; -#endif /* HAVE_SIGACTION */ - -/* - * Global LDAP session. - */ -static struct ldap_session __session = { NULL, NULL, 0, LS_UNINITIALIZED }; - -#if defined(HAVE_PTHREAD_ATFORK) || defined(HAVE_LIBC_LOCK_H) || defined(HAVE_BITS_LIBC_LOCK_H) -static pthread_once_t __once = PTHREAD_ONCE_INIT; -#endif - -#ifdef LBER_OPT_LOG_PRINT_FILE -static FILE *__debugfile; -#endif /* LBER_OPT_LOG_PRINT_FILE */ - -#ifndef HAVE_PTHREAD_ATFORK -/* - * Process ID that opened the session. - */ -static pid_t __pid = -1; -#endif -static uid_t __euid = -1; - -#ifdef HAVE_LDAPSSL_CLIENT_INIT -static int __ssl_initialized = 0; -#endif /* HAVE_LDAPSSL_CLIENT_INIT */ - -#if defined(HAVE_PTHREAD_ATFORK) || defined(HAVE_LIBC_LOCK_H) || defined(HAVE_BITS_LIBC_LOCK_H) -/* - * Prepare for fork(); lock mutex. - */ -static void do_atfork_prepare (void); - -/* - * Forked in parent, unlock mutex. - */ -static void do_atfork_parent (void); - -/* - * Forked in child; close LDAP socket, unlock mutex. - */ -static void do_atfork_child (void); - -/* - * Install handlers for atfork, called once. - */ -static void do_atfork_setup (void); -#endif - -/* - * Close the global session, sending an unbind. - */ -static void do_close (void); - -/* - * Close the global session without sending an unbind. - */ -static void do_close_no_unbind (void); - -/* - * Disable keepalive on a LDAP connection's socket. - */ -static void do_set_sockopts (void); - -/* - * TLS routines: set global SSL session options. - */ -#if defined(HAVE_LDAP_START_TLS_S) || defined(HAVE_LDAP_START_TLS) || (defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS)) -static int do_ssl_options (struct ldap_config * cfg); -static int do_start_tls (struct ldap_session * session); -#endif - -/* - * Function to be braced by reconnect harness. Used so we - * can apply the reconnect code to both asynchronous and - * synchronous searches. - */ -typedef int (*search_func_t) (const char *, int, const char *, - const char **, int, void *); - -static enum nss_status -do_map_error (int rc) -{ - enum nss_status stat; - - switch (rc) - { - case LDAP_SUCCESS: - case LDAP_SIZELIMIT_EXCEEDED: - case LDAP_TIMELIMIT_EXCEEDED: - stat = NSS_STATUS_SUCCESS; - break; - case LDAP_NO_SUCH_ATTRIBUTE: - case LDAP_UNDEFINED_TYPE: - case LDAP_INAPPROPRIATE_MATCHING: - case LDAP_CONSTRAINT_VIOLATION: - case LDAP_TYPE_OR_VALUE_EXISTS: - case LDAP_INVALID_SYNTAX: - case LDAP_NO_SUCH_OBJECT: - case LDAP_ALIAS_PROBLEM: - case LDAP_INVALID_DN_SYNTAX: - case LDAP_IS_LEAF: - case LDAP_ALIAS_DEREF_PROBLEM: - case LDAP_FILTER_ERROR: - stat = NSS_STATUS_NOTFOUND; - break; - case LDAP_SERVER_DOWN: - case LDAP_TIMEOUT: - case LDAP_UNAVAILABLE: - case LDAP_BUSY: -#ifdef LDAP_CONNECT_ERROR - case LDAP_CONNECT_ERROR: -#endif /* LDAP_CONNECT_ERROR */ - case LDAP_LOCAL_ERROR: - case LDAP_INVALID_CREDENTIALS: - default: - stat = NSS_STATUS_UNAVAIL; - break; - } - return stat; -} - -#if defined(HAVE_LDAP_SASL_INTERACTIVE_BIND_S) && (defined(HAVE_SASL_H) ||defined (HAVE_SASL_SASL_H)) -static int -do_sasl_interact (LDAP * ld, unsigned flags, void *defaults, void *_interact) -{ - char *authzid = (char *) defaults; - sasl_interact_t *interact = (sasl_interact_t *) _interact; - - while (interact->id != SASL_CB_LIST_END) - { - if (interact->id == SASL_CB_USER) - { - if (authzid != NULL) - { - interact->result = authzid; - interact->len = strlen (authzid); - } - else if (interact->defresult != NULL) - { - interact->result = interact->defresult; - interact->len = strlen (interact->defresult); - } - else - { - interact->result = ""; - interact->len = 0; - } -#if SASL_VERSION_MAJOR < 2 - interact->result = strdup (interact->result); - if (interact->result == NULL) - { - return LDAP_NO_MEMORY; - } -#endif /* SASL_VERSION_MAJOR < 2 */ - } - else - { - return LDAP_PARAM_ERROR; - } - interact++; - } - return LDAP_SUCCESS; -} -#endif - -static int -do_bind (LDAP * ld, int timelimit, const char *dn, const char *pw, - int with_sasl) -{ - int rc; - int msgid; - struct timeval tv; - LDAPMessage *result; - - debug("==> do_bind"); - - /* - * set timelimit in ld for select() call in ldap_pvt_connect() - * function implemented in libldap2's os-ip.c - */ - tv.tv_sec = timelimit; - tv.tv_usec = 0; - -#if (defined(HAVE_LDAP_SASL_INTERACTIVE_BIND_S) && (defined(HAVE_SASL_H) || defined(HAVE_SASL_SASL_H))) || defined(HAVE_LDAP_GSS_BIND) - if (!with_sasl) - { -#endif - msgid = ldap_simple_bind (ld, dn, pw); - - if (msgid < 0) - { - if (ldap_get_option (ld, LDAP_OPT_ERROR_NUMBER, &rc) != - LDAP_SUCCESS) - { - rc = LDAP_UNAVAILABLE; - } - /* Notify if we failed. */ - syslog (LOG_AUTHPRIV | LOG_ERR, "nss_ldap: could not connect to any LDAP server as %s - %s", - dn, ldap_err2string (rc)); - debug ("<== do_bind"); - - return rc; - } - - rc = ldap_result (ld, msgid, 0, &tv, &result); - if (rc > 0) - { - debug ("<== do_bind"); - return ldap_result2error (ld, result, 1); - } - - /* took too long */ - if (rc == 0) - { - ldap_abandon (ld, msgid); - } -#if (defined(HAVE_LDAP_SASL_INTERACTIVE_BIND_S) && (defined(HAVE_SASL_H) || defined(HAVE_SASL_SASL_H))) || defined(HAVE_LDAP_GSS_BIND) - } - else - { -#ifdef HAVE_LDAP_GSS_BIND - return ldap_gss_bind (ld, dn, pw, GSSSASL_NO_SECURITY_LAYER, - LDAP_SASL_GSSAPI); -#else -#ifdef CONFIGURE_KRB5_CCNAME -#ifndef CONFIGURE_KRB5_CCNAME_GSSAPI - char tmpbuf[256]; - static char envbuf[256]; -#endif - char *ccname; - const char *oldccname = NULL; - int retval; -#endif /* CONFIGURE_KRB5_CCNAME */ - - if (__config->ldc_sasl_secprops != NULL) - { - rc = - ldap_set_option (ld, LDAP_OPT_X_SASL_SECPROPS, - (void *) __config->ldc_sasl_secprops); - if (rc != LDAP_SUCCESS) - { - debug ("do_bind: unable to set SASL security properties"); - return rc; - } - } - -#ifdef CONFIGURE_KRB5_CCNAME - /* Set default Kerberos ticket cache for SASL-GSSAPI */ - /* There are probably race conditions here XXX */ - if (__config->ldc_krb5_ccname != NULL) - { - ccname = __config->ldc_krb5_ccname; -#ifdef CONFIGURE_KRB5_CCNAME_ENV - oldccname = getenv ("KRB5CCNAME"); - if (oldccname != NULL) - { - strncpy (tmpbuf, oldccname, sizeof (tmpbuf)); - tmpbuf[sizeof (tmpbuf) - 1] = '\0'; - } - else - { - tmpbuf[0] = '\0'; - } - oldccname = tmpbuf; - snprintf (envbuf, sizeof (envbuf), "KRB5CCNAME=%s", ccname); - putenv (envbuf); -#elif defined(CONFIGURE_KRB5_CCNAME_GSSAPI) - if (gss_krb5_ccache_name (&retval, ccname, &oldccname) != - GSS_S_COMPLETE) - { - debug ("do_bind: unable to set default credential cache"); - return -1; - } -#endif - } -#endif /* CONFIGURE_KRB5_CCNAME */ - - rc = ldap_sasl_interactive_bind_s (ld, dn, "GSSAPI", NULL, NULL, - LDAP_SASL_QUIET, - do_sasl_interact, (void *) pw); - -#ifdef CONFIGURE_KRB5_CCNAME - /* Restore default Kerberos ticket cache. */ - if (oldccname != NULL) - { -#ifdef CONFIGURE_KRB5_CCNAME_ENV - snprintf (envbuf, sizeof (envbuf), "KRB5CCNAME=%s", oldccname); - putenv (envbuf); -#elif defined(CONFIGURE_KRB5_CCNAME_GSSAPI) - if (gss_krb5_ccache_name (&retval, oldccname, NULL) != - GSS_S_COMPLETE) - { - debug ("do_bind: unable to restore default credential cache"); - return -1; - } -#endif - } -#endif /* CONFIGURE_KRB5_CCNAME */ - - return rc; -#endif /* HAVE_LDAP_GSS_BIND */ - } -#endif - - debug ("<== do_bind"); - - return -1; -} - -/* - * Rebind functions. - */ - -#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) -#if LDAP_SET_REBIND_PROC_ARGS == 3 -static int -do_rebind (LDAP * ld, LDAP_CONST char *url, ber_tag_t request, - ber_int_t msgid, void *arg) -#else -static int -do_rebind (LDAP * ld, LDAP_CONST char *url, int request, ber_int_t msgid) -#endif -{ - char *who, *cred; - int timelimit; - int with_sasl = 0; - - if (geteuid () == 0 && __session.ls_config->ldc_rootbinddn) - { - who = __session.ls_config->ldc_rootbinddn; -#if defined(HAVE_LDAP_SASL_INTERACTIVE_BIND_S) && (defined(HAVE_SASL_H) || defined(HAVE_SASL_SASL_H)) - with_sasl = __session.ls_config->ldc_rootusesasl; - if (with_sasl) - { - cred = __session.ls_config->ldc_rootsaslid; - } - else - { -#endif - cred = __session.ls_config->ldc_rootbindpw; -#if defined(HAVE_LDAP_SASL_INTERACTIVE_BIND_S) && (defined(HAVE_SASL_H) || defined(HAVE_SASL_SASL_H)) - } -#endif - } - else - { - who = __session.ls_config->ldc_binddn; -#if defined(HAVE_LDAP_SASL_INTERACTIVE_BIND_S) && (defined(HAVE_SASL_H) || defined(HAVE_SASL_SASL_H)) - with_sasl = __session.ls_config->ldc_usesasl; - if (with_sasl) - { - cred = __session.ls_config->ldc_saslid; - } - else - { -#endif - cred = __session.ls_config->ldc_bindpw; -#if defined(HAVE_LDAP_SASL_INTERACTIVE_BIND_S) && (defined(HAVE_SASL_H) || defined(HAVE_SASL_SASL_H)) - } -#endif - } - - timelimit = __session.ls_config->ldc_bind_timelimit; - -#ifdef HAVE_LDAP_START_TLS_S - if (__session.ls_config->ldc_ssl_on == SSL_START_TLS) - { - int version; - - if (ldap_get_option - (__session.ls_conn, LDAP_OPT_PROTOCOL_VERSION, - &version) == LDAP_OPT_SUCCESS) - { - if (version < LDAP_VERSION3) - { - version = LDAP_VERSION3; - ldap_set_option (__session.ls_conn, LDAP_OPT_PROTOCOL_VERSION, - &version); - } - } - - if (do_start_tls (&__session) == LDAP_SUCCESS) - { - debug ("TLS startup succeeded"); - } - else - { - debug ("TLS startup failed"); - return NSS_STATUS_UNAVAIL; - } - } -#endif /* HAVE_LDAP_START_TLS_S */ - - return do_bind (ld, timelimit, who, cred, with_sasl); -} -#else -#if LDAP_SET_REBIND_PROC_ARGS == 3 -static int -do_rebind (LDAP * ld, char **whop, char **credp, int *methodp, - int freeit, void *arg) -#elif LDAP_SET_REBIND_PROC_ARGS == 2 -static int -do_rebind (LDAP * ld, char **whop, char **credp, int *methodp, int freeit) -#endif -{ - if (freeit) - { - if (*whop != NULL) - free (*whop); - if (*credp != NULL) - free (*credp); - } - - *whop = *credp = NULL; - if (geteuid () == 0 && __session.ls_config->ldc_rootbinddn) - { - *whop = strdup (__session.ls_config->ldc_rootbinddn); - if (__session.ls_config->ldc_rootbindpw != NULL) - *credp = strdup (__session.ls_config->ldc_rootbindpw); - } - else - { - if (__session.ls_config->ldc_binddn != NULL) - *whop = strdup (__session.ls_config->ldc_binddn); - if (__session.ls_config->ldc_bindpw != NULL) - *credp = strdup (__session.ls_config->ldc_bindpw); - } - - *methodp = LDAP_AUTH_SIMPLE; - - return LDAP_SUCCESS; -} -#endif - -static void -_nss_ldap_block_sigpipe (void) -{ -#ifdef HAVE_SIGACTION - struct sigaction new_handler; - - memset (&new_handler, 0, sizeof (new_handler)); -#if 0 - /* XXX need to test for sa_sigaction, not on all platforms */ - new_handler.sa_sigaction = NULL; -#endif - new_handler.sa_handler = SIG_IGN; - sigemptyset (&new_handler.sa_mask); - new_handler.sa_flags = 0; -#endif /* HAVE_SIGACTION */ - - /* - * Patch for Debian Bug 130006: - * ignore SIGPIPE for all LDAP operations. - * - * The following bug was reintroduced in nss_ldap-213 and is fixed here: - * http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=84344 - * - * See: - * http://www.gnu.org/software/libc/manual/html_node/Signal-and-Sigaction.html - * for more details. - */ -#ifdef HAVE_SIGACTION - __sigaction_retval = sigaction (SIGPIPE, &new_handler, &__stored_handler); -#elif defined(HAVE_SIGSET) - __sigpipe_handler = sigset (SIGPIPE, SIG_IGN); -#else - __sigpipe_handler = signal (SIGPIPE, SIG_IGN); -#endif /* HAVE_SIGSET */ -} - -static void -_nss_ldap_unblock_sigpipe (void) -{ -#ifdef HAVE_SIGACTION - if (__sigaction_retval == 0) - (void) sigaction (SIGPIPE, &__stored_handler, NULL); -#else - if (__sigpipe_handler != SIG_ERR && __sigpipe_handler != SIG_IGN) - { -#ifdef HAVE_SIGSET - (void) sigset (SIGPIPE, __sigpipe_handler); -#else - (void) signal (SIGPIPE, __sigpipe_handler); -#endif /* HAVE_SIGSET */ - } -#endif /* HAVE_SIGACTION */ -} - -#if defined(HAVE_PTHREAD_ATFORK) || defined(HAVE_LIBC_LOCK_H) || defined(HAVE_BITS_LIBC_LOCK_H) -static void -do_atfork_prepare (void) -{ - debug ("==> do_atfork_prepare"); - NSS_LDAP_LOCK (__lock); - debug ("<== do_atfork_prepare"); -} - -static void -do_atfork_parent (void) -{ - debug ("==> do_atfork_parent"); - NSS_LDAP_UNLOCK (__lock); - debug ("<== do_atfork_parent"); -} - -static void -do_atfork_child (void) -{ - debug ("==> do_atfork_child"); - _nss_ldap_block_sigpipe(); - do_close_no_unbind (); - _nss_ldap_unblock_sigpipe(); - NSS_LDAP_UNLOCK (__lock); - debug ("<== do_atfork_child"); -} - -static void -do_atfork_setup (void) -{ - debug ("==> do_atfork_setup"); - -#ifdef HAVE_PTHREAD_ATFORK - (void) pthread_atfork (do_atfork_prepare, do_atfork_parent, - do_atfork_child); -#elif defined(HAVE_LIBC_LOCK_H) || defined(HAVE_BITS_LIBC_LOCK_H) - (void) __libc_atfork (do_atfork_prepare, do_atfork_parent, do_atfork_child); -#endif - - debug ("<== do_atfork_setup"); -} -#endif - -/* - * Acquires global lock, blocks SIGPIPE. - */ -void -_nss_ldap_enter (void) -{ - debug ("==> _nss_ldap_enter"); - - NSS_LDAP_LOCK (__lock); - _nss_ldap_block_sigpipe(); - - debug ("<== _nss_ldap_enter"); -} - -/* - * Releases global mutex, releases SIGPIPE. - */ -void -_nss_ldap_leave (void) -{ - debug ("==> _nss_ldap_leave"); - - _nss_ldap_unblock_sigpipe(); - NSS_LDAP_UNLOCK (__lock); - - debug ("<== _nss_ldap_leave"); -} - -static void -do_set_sockopts (void) -{ -/* - * Netscape SSL-enabled LDAP library does not - * return the real socket. - */ -#ifndef HAVE_LDAPSSL_CLIENT_INIT - int sd = -1; - - debug ("==> do_set_sockopts"); - if (ldap_get_option (__session.ls_conn, LDAP_OPT_DESC, &sd) == 0) - { - int off = 0; - socklen_t socknamelen = sizeof (struct sockaddr_storage); - socklen_t peernamelen = sizeof (struct sockaddr_storage); - - (void) setsockopt (sd, SOL_SOCKET, SO_KEEPALIVE, (void *) &off, - sizeof (off)); - (void) fcntl (sd, F_SETFD, FD_CLOEXEC); - /* - * NSS modules shouldn't open file descriptors that the program/utility - * linked against NSS doesn't know about. The LDAP library opens a - * connection to the LDAP server transparently. There's an edge case - * where a daemon might fork a child and, being written well, closes - * all its file descriptors. This will close the socket descriptor - * being used by the LDAP library! Worse, the daemon might open many - * files and sockets, eventually opening a descriptor with the same number - * as that originally used by the LDAP library. The only way to know that - * this isn't "our" socket descriptor is to save the local and remote - * sockaddr_in structures for later comparison. - */ - (void) getsockname (sd, (struct sockaddr *) &__session.ls_sockname, - &socknamelen); - (void) getpeername (sd, (struct sockaddr *) &__session.ls_peername, - &peernamelen); - } - debug ("<== do_set_sockopts"); -#endif /* HAVE_LDAPSSL_CLIENT_INIT */ - - return; -} - -/* - * Closes connection to the LDAP server. - * This assumes that we have exclusive access to __session.ls_conn, - * either by some other function having acquired a lock, or by - * using a thread safe libldap. - */ -static void -do_close (void) -{ -#if defined(DEBUG) || defined(DEBUG_SOCKETS) - int sd = -1; -#endif - - debug ("==> do_close"); - - if (__session.ls_conn != NULL) - { -#if defined(DEBUG) || defined(DEBUG_SOCKETS) -#if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_DESC) - ldap_get_option (__session.ls_conn, LDAP_OPT_DESC, &sd); -#else - sd = __session.ls_conn->ld_sb.sb_sd; -#endif /* LDAP_OPT_DESC */ - syslog (LOG_AUTHPRIV | LOG_INFO, "nss_ldap: closing connection %p fd %d", - (void *)__session.ls_conn, sd); -#endif /* DEBUG */ - - ldap_unbind (__session.ls_conn); - __session.ls_conn = NULL; - __session.ls_state = LS_UNINITIALIZED; - } - - debug ("<== do_close"); -} - -static int -do_sockaddr_isequal (struct sockaddr_storage *_s1, - socklen_t _slen1, - struct sockaddr_storage *_s2, - socklen_t _slen2) -{ - int ret; - - if (_s1->ss_family != _s2->ss_family) - return 0; - - if (_slen1 != _slen2) - return 0; - - ret = 0; - - switch (_s1->ss_family) - { - case AF_INET: - { - struct sockaddr_in *s1 = (struct sockaddr_in *) _s1; - struct sockaddr_in *s2 = (struct sockaddr_in *) _s2; - - ret = (s1->sin_port == s2->sin_port && - memcmp (&s1->sin_addr, &s2->sin_addr, sizeof(struct in_addr)) == 0); - break; - } - case AF_UNIX: - { - struct sockaddr_un *s1 = (struct sockaddr_un *) _s1; - struct sockaddr_un *s2 = (struct sockaddr_un *) _s2; - - ret = (memcmp (s1->sun_path, s2->sun_path, - _slen1 - sizeof (_s1->ss_family)) == 0); - break; - } -#ifdef INET6 - case AF_INET6: - { - struct sockaddr_in6 *s1 = (struct sockaddr_in6 *) _s1; - struct sockaddr_in6 *s2 = (struct sockaddr_in6 *) _s2; - - ret = (s1->sin6_port == s2->sin6_port && - memcmp (&s1->sin6_addr, &s2->sin6_addr, sizeof(struct in6_addr)) == 0 && - s1->sin6_scope_id == s2->sin6_scope_id); - break; - } -#endif - default: - ret = (memcmp (_s1, _s2, _slen1) == 0); - break; - } - - return ret; -} - -static int -do_get_our_socket(int *sd) -{ - /* - * Before freeing the LDAP context or closing the socket descriptor, - * we must ensure that it is *our* socket descriptor. See the much - * lengthier description of this at the end of do_open () where the - * values __session.ls_sockname and __session.ls_peername are saved. - * With HAVE_LDAPSSL_CLIENT_INIT this returns 0 if the socket has - * been closed or reopened, and sets *sd to the ldap socket - * descriptor.. Returns 1 in all other cases. - */ - - int isOurSocket = 1; - -#ifndef HAVE_LDAPSSL_CLIENT_INIT - if (ldap_get_option (__session.ls_conn, LDAP_OPT_DESC, sd) == 0) - { - struct sockaddr_storage sockname; - struct sockaddr_storage peername; - socklen_t socknamelen = sizeof (sockname); - socklen_t peernamelen = sizeof (peername); - - if (getsockname (*sd, (struct sockaddr *) &sockname, &socknamelen) != 0 || - getpeername (*sd, (struct sockaddr *) &peername, &peernamelen) != 0) - { - isOurSocket = 0; - } - else - { - isOurSocket = do_sockaddr_isequal (&__session.ls_sockname, - socknamelen, - &sockname, - socknamelen); - if (isOurSocket) - { - isOurSocket = do_sockaddr_isequal (&__session.ls_peername, - peernamelen, - &peername, - peernamelen); - } - } - } -#endif /* HAVE_LDAPSSL_CLIENT_INIT */ - return isOurSocket; -} - -static int -do_dupfd(int oldfd, int newfd) -{ - int d = -1; - int flags; - - flags = fcntl(oldfd, F_GETFD); - - while (1) - { - d = (newfd > -1) ? dup2 (oldfd, newfd) : dup (oldfd); - if (d > -1) - break; - - if (errno == EBADF) - return -1; /* not open */ - - if (errno != EINTR -#ifdef EBUSY - && errno != EBUSY -#endif - ) - return -1; - } - - /* duplicate close-on-exec flag */ - (void) fcntl (d, F_SETFD, flags); - - return d; -} - -static int -do_closefd(int fd) -{ - int rc; - - while ((rc = close(fd)) < 0 && errno == EINTR) - ; - - return rc; -} - -static void -do_drop_connection(int sd, int closeSd) -{ - /* Close the LDAP connection without writing anything to the - underlying socket. The socket will be left open afterwards if - closeSd is 0 */ -#ifndef HAVE_LDAPSSL_CLIENT_INIT - { - int dummyfd = -1, savedfd = -1; - /* Under OpenLDAP 2.x, ldap_set_option (..., LDAP_OPT_DESC, ...) is - a no-op, so to shut down the LDAP connection without writing - anything to the socket, we swap a dummy socket onto that file - descriptor, and then swap the real fd back once the shutdown is - done. */ - savedfd = do_dupfd (sd, -1); - dummyfd = socket (AF_INET, SOCK_STREAM, 0); - if (dummyfd > -1 && dummyfd != sd) - { - do_closefd (sd); - do_dupfd (dummyfd, sd); - do_closefd (dummyfd); - } - -#ifdef HAVE_LDAP_LD_FREE -#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) - (void) ldap_ld_free (__session.ls_conn, 0, NULL, NULL); -#else - (void) ldap_ld_free (__session.ls_conn, 0); -#endif /* OPENLDAP 2.x */ -#else - ldap_unbind (__session.ls_conn); -#endif /* HAVE_LDAP_LD_FREE */ - - /* Do we want our original sd back? */ - do_closefd (sd); - if (savedfd > -1) - { - if (closeSd == 0) - do_dupfd (savedfd, sd); - do_closefd (savedfd); - } - } -#else /* No sd available */ - { - int bogusSd = -1; - if (closeSd == 0) - { - sd = -1; /* don't want to really close the socket */ -#ifdef HAVE_LDAP_LD_FREE -#if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_DESC) - (void) ldap_set_option (__session.ls_conn, LDAP_OPT_DESC, &sd); -#else - __session.ls_conn->ld_sb.sb_sd = -1; -#endif /* LDAP_OPT_DESC */ -#endif /* HAVE_LDAP_LD_FREE */ - } - -#ifdef HAVE_LDAP_LD_FREE - -#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) - (void) ldap_ld_free (__session.ls_conn, 0, NULL, NULL); -#else - (void) ldap_ld_free (__session.ls_conn, 0); -#endif /* OPENLDAP 2.x */ - -#else - -#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_DESC) - (void) ldap_set_option (__session.ls_conn, LDAP_OPT_DESC, &bogusSd); -#else - __session.ls_conn->ld_sb.sb_sd = bogusSd; -#endif /* LDAP_OPT_DESC */ - - /* hope we closed it OK! */ - ldap_unbind (__session.ls_conn); - -#endif /* HAVE_LDAP_LD_FREE */ - - } -#endif /* HAVE_LDAPSSL_CLIENT_INIT */ - __session.ls_conn = NULL; - __session.ls_state = LS_UNINITIALIZED; - - return; -} - -/* - * If we've forked, then we need to open a new session. - * Careful: we have the socket shared with our parent, - * so we don't want to send an unbind to the server. - * However, we want to close the descriptor to avoid - * leaking it, and we also want to release the memory - * used by __session.ls_conn. The only entry point - * we have is ldap_unbind() which does both of these - * things, so we use an internal API, at the expense - * of compatibility. - */ -static void -do_close_no_unbind (void) -{ - int sd = -1; - int closeSd = 1; - - debug ("==> do_close_no_unbind"); - - if (__session.ls_state == LS_UNINITIALIZED) - { - assert (__session.ls_conn == NULL); - debug ("<== do_close_no_unbind (connection was not open)"); - return; - } - - closeSd = do_get_our_socket (&sd); - -#if defined(DEBUG) || defined(DEBUG_SOCKETS) - syslog (LOG_AUTHPRIV | LOG_INFO, "nss_ldap: %sclosing connection (no unbind) %p fd %d", - closeSd ? "" : "not ", (void *)__session.ls_conn, sd); -#endif /* DEBUG */ - - do_drop_connection(sd, closeSd); - - debug ("<== do_close_no_unbind"); - - return; -} - -static enum nss_status -do_init_session (LDAP ** ld, const char *uri, int defport) -{ - int rc; - int ldaps; - char uribuf[NSS_BUFSIZ]; - char *p; - enum nss_status stat; - - ldaps = (strncasecmp (uri, "ldaps://", sizeof ("ldaps://") - 1) == 0); - p = strchr (uri, ':'); - /* we should be looking for the second instance to find the port number */ - if (p != NULL) - { - p = strchr (p, ':'); - } - -#ifdef HAVE_LDAP_INITIALIZE - if (p == NULL && - ((ldaps && defport != LDAPS_PORT) || (!ldaps && defport != LDAP_PORT))) - { - /* No port specified in URI and non-default port specified */ - snprintf (uribuf, sizeof (uribuf), "%s:%d", uri, defport); - uri = uribuf; - } - - rc = ldap_initialize (ld, uri); -#else - if (strncasecmp (uri, "ldap://", sizeof ("ldap://") - 1) != 0) - { - return NSS_STATUS_UNAVAIL; - } - - uri += sizeof ("ldap://") - 1; - p = strchr (uri, ':'); - - if (p != NULL) - { - size_t urilen = (p - uri); - - if (urilen >= sizeof (uribuf)) - { - return NSS_STATUS_UNAVAIL; - } - - memcpy (uribuf, uri, urilen); - uribuf[urilen] = '\0'; - - defport = atoi (p + 1); - uri = uribuf; - } - -#ifdef HAVE_LDAP_INIT - *ld = ldap_init (uri, defport); -#else - *ld = ldap_open (uri, defport); -#endif - - rc = (*ld == NULL) ? LDAP_SERVER_DOWN : LDAP_SUCCESS; - -#endif /* HAVE_LDAP_INITIALIZE */ - - stat = do_map_error (rc); - if (stat == NSS_STATUS_SUCCESS && *ld == NULL) - { - stat = NSS_STATUS_UNAVAIL; - } - return stat; -} - -static enum nss_status -do_init (void) -{ - struct ldap_config *cfg; -#ifndef HAVE_PTHREAD_ATFORK - pid_t pid; -#endif - uid_t euid; - enum nss_status stat; - int sd=-1; - - debug ("==> do_init"); - - if (_nss_ldap_validateconfig (__config) != NSS_STATUS_SUCCESS) - { - do_close (); - __config = NULL; - __session.ls_current_uri = 0; - } - -#ifndef HAVE_PTHREAD_ATFORK -#if defined(HAVE_LIBC_LOCK_H) || defined(HAVE_BITS_LIBC_LOCK_H) - /* - * This bogosity is necessary because Linux uses different - * PIDs for different threads (like IRIX, which we don't - * support). We can tell whether we are linked against - * libpthreads by whether __pthread_once is NULL or - * not. If it is NULL, then we're not linked with the - * threading library, and we need to compare the current - * process ID against the saved one to figure out - * whether we've forked. - * - * Once we know whether we have forked or not, - * courtesy of pthread_atfork() or us checking - * ourselves, we can close the socket to the LDAP - * server to avoid leaking a socket, and reopen - * another connection. Under no circumstances do we - * wish to use the same connection, or to send an - * unbind PDU over the parents connection, as that - * will wreak all sorts of havoc or inefficiencies, - * respectively. - */ - if (__pthread_once == NULL) - pid = getpid (); - else - pid = -1; /* linked against libpthreads, don't care */ -#else - pid = getpid (); -#endif /* HAVE_LIBC_LOCK_H || HAVE_BITS_LIBC_LOCK_H */ -#endif /* HAVE_PTHREAD_ATFORK */ - - euid = geteuid (); - -#ifdef DEBUG -#ifdef HAVE_PTHREAD_ATFORK - syslog (LOG_AUTHPRIV | LOG_DEBUG, - "nss_ldap: __session.ls_state=%d, __session.ls_conn=%p, __euid=%i, euid=%i", - __session.ls_state, __session.ls_conn, __euid, euid); -#elif defined(HAVE_LIBC_LOCK_H) || defined(HAVE_BITS_LIBC_LOCK_H) - syslog (LOG_AUTHPRIV | LOG_DEBUG, - "nss_ldap: libpthreads=%s, __session.ls_state=%d, __session.ls_conn=%p, __pid=%i, pid=%i, __euid=%i, euid=%i", - (__pthread_once == NULL ? "FALSE" : "TRUE"), - __session.ls_state, - (void *)__session.ls_conn, - (__pthread_once == NULL ? __pid : -1), - (__pthread_once == NULL ? pid : -1), __euid, euid); -#else - syslog (LOG_AUTHPRIV | LOG_DEBUG, - "nss_ldap: __session.ls_state=%d, __session.ls_conn=%p, __pid=%i, pid=%i, __euid=%i, euid=%i", - __session.ls_state, __session.ls_conn, __pid, pid, __euid, euid); -#endif -#endif /* DEBUG */ - - if (__session.ls_state == LS_CONNECTED_TO_DSA && - do_get_our_socket (&sd) == 0) - { - /* The calling app has stolen our socket. */ - debug (":== do_init (stolen socket detected)"); - do_drop_connection (sd, 0); - } - else -#ifndef HAVE_PTHREAD_ATFORK -#if defined(HAVE_LIBC_LOCK_H) || defined(HAVE_BITS_LIBC_LOCK_H) - if (__pthread_once == NULL && __pid != pid) -#else - if (__pid != pid) -#endif /* HAVE_LIBC_LOCK_H || HAVE_BITS_LIBC_LOCK_H */ - { - do_close_no_unbind (); - } - else -#endif /* HAVE_PTHREAD_ATFORK */ - if (__euid != euid && (__euid == 0 || euid == 0)) - { - /* - * If we've changed user ids, close the session so we can - * rebind as the correct user. - */ - do_close (); - } - else if (__session.ls_state == LS_CONNECTED_TO_DSA) - { - time_t current_time; - - /* - * Otherwise we can hand back this process' global - * LDAP session. - * - * Patch from Steven Barrus <sbarrus@eng.utah.edu> to - * close the session after an idle timeout. - */ - - assert (__session.ls_conn != NULL); - assert (__session.ls_config != NULL); - - if (__session.ls_config->ldc_idle_timelimit) - { - time (¤t_time); - if ((__session.ls_timestamp + - __session.ls_config->ldc_idle_timelimit) < current_time) - { - debug ("idle_timelimit reached"); - do_close (); - } - } - - /* - * If the connection is still there (ie. do_close() wasn't - * called) then we can return the cached connection. - */ - if (__session.ls_state == LS_CONNECTED_TO_DSA) - { - debug ("<== do_init (cached session)"); - return NSS_STATUS_SUCCESS; - } - } - - __session.ls_conn = NULL; - __session.ls_timestamp = 0; - __session.ls_state = LS_UNINITIALIZED; - -#ifdef HAVE_PTHREAD_ATFORK - if (pthread_once (&__once, do_atfork_setup) != 0) - { - debug ("<== do_init (pthread_once failed)"); - return NSS_STATUS_UNAVAIL; - } -#elif defined(HAVE_LIBC_LOCK_H) || defined(HAVE_BITS_LIBC_LOCK_H) - /* - * Only install the pthread_atfork() handlers i - * we are linked against libpthreads. Otherwise, - * do close the session when the PID changes. - */ - if (__pthread_once == NULL) - __pid = pid; - else - __libc_once (__once, do_atfork_setup); -#else - __pid = pid; -#endif - - __euid = euid; - - /* Initialize schema and LDAP handle (but do not connect) */ - if (__config == NULL) - { - char *configbufp = __configbuf; - size_t configbuflen = sizeof (__configbuf); - - stat = _nss_ldap_readconfig (&__config, &configbufp, &configbuflen); - if (stat == NSS_STATUS_NOTFOUND) - { - /* Config was read but no host information specified; try DNS */ - stat = _nss_ldap_mergeconfigfromdns (__config, &configbufp, &configbuflen); - } - - if (stat != NSS_STATUS_SUCCESS) - { - debug ("<== do_init (failed to read config)"); - return NSS_STATUS_UNAVAIL; - } - } - - cfg = __config; - - _nss_ldap_init_attributes (cfg->ldc_attrtab); - _nss_ldap_init_filters (); - -#ifdef HAVE_LDAP_SET_OPTION - if (cfg->ldc_debug) - { -#ifdef LBER_OPT_LOG_PRINT_FILE - if (cfg->ldc_logdir && !__debugfile) - { - char namebuf[PATH_MAX]; - - snprintf (namebuf, sizeof (namebuf), "%s/ldap.%d", cfg->ldc_logdir, - (int) getpid ()); - __debugfile = fopen (namebuf, "a"); - - if (__debugfile != NULL) - { - ber_set_option (NULL, LBER_OPT_LOG_PRINT_FILE, __debugfile); - } - } -#endif /* LBER_OPT_LOG_PRINT_FILE */ -#ifdef LBER_OPT_DEBUG_LEVEL - if (cfg->ldc_debug) - { - ber_set_option (NULL, LBER_OPT_DEBUG_LEVEL, &cfg->ldc_debug); - ldap_set_option (NULL, LDAP_OPT_DEBUG_LEVEL, &cfg->ldc_debug); - } -#endif /* LBER_OPT_DEBUG_LEVEL */ - } -#endif /* HAVE_LDAP_SET_OPTION */ - -#ifdef HAVE_LDAPSSL_CLIENT_INIT - /* - * Initialize the SSL library. - */ - if (cfg->ldc_ssl_on == SSL_LDAPS) - { - int rc = 0; - if (__ssl_initialized == 0 - && (rc = ldapssl_client_init (cfg->ldc_sslpath, NULL)) != LDAP_SUCCESS) - { - debug ("<== do_init (ldapssl_client_init failed with rc = %d)", rc); - return NSS_STATUS_UNAVAIL; - } - __ssl_initialized = 1; - } -#endif /* SSL */ - - __session.ls_conn = NULL; - - assert (__session.ls_current_uri <= NSS_LDAP_CONFIG_URI_MAX); - assert (cfg->ldc_uris[__session.ls_current_uri] != NULL); - - stat = do_init_session (&__session.ls_conn, - cfg->ldc_uris[__session.ls_current_uri], - cfg->ldc_port); - if (stat != NSS_STATUS_SUCCESS) - { - debug ("<== do_init (failed to initialize LDAP session)"); - return stat; - } - - __session.ls_config = cfg; - __session.ls_state = LS_INITIALIZED; - - debug ("<== do_init (initialized session)"); - - return NSS_STATUS_SUCCESS; -} - -/* - * A simple alias around do_init(). - */ -enum nss_status -_nss_ldap_init (void) -{ - return do_init (); -} - -/* - * A simple alias around do_close(). - */ -void -_nss_ldap_close (void) -{ - do_close (); -} - -#if defined(HAVE_LDAP_START_TLS_S) || defined(HAVE_LDAP_START_TLS) -static int -do_start_tls (struct ldap_session * session) -{ - int rc; -#ifdef HAVE_LDAP_START_TLS - int msgid; - struct timeval tv, *timeout; - LDAPMessage *res = NULL; - - debug ("==> do_start_tls"); - - rc = ldap_start_tls (session->ls_conn, NULL, NULL, &msgid); - if (rc != LDAP_SUCCESS) - { - debug ("<== do_start_tls (ldap_start_tls failed: %s)", ldap_err2string (rc)); - return rc; - } - - if (session->ls_config->ldc_bind_timelimit == LDAP_NO_LIMIT) - { - timeout = NULL; - } - else - { - tv.tv_sec = session->ls_config->ldc_bind_timelimit; - tv.tv_usec = 0; - timeout = &tv; - } - - rc = ldap_result (session->ls_conn, msgid, 1, timeout, &res); - if (rc == -1) - { -#if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_ERROR_NUMBER) - if (ldap_get_option (session->ls_conn, LDAP_OPT_ERROR_NUMBER, &rc) != LDAP_SUCCESS) - { - rc = LDAP_UNAVAILABLE; - } -#else - rc = ld->ld_errno; -#endif /* LDAP_OPT_ERROR_NUMBER */ - - debug ("<== do_start_tls (ldap_start_tls failed: %s)", ldap_err2string (rc)); - return rc; - } - - rc = ldap_result2error (session->ls_conn, res, 1); - if (rc != LDAP_SUCCESS) - { - debug ("<== do_start_tls (ldap_result2error failed: %s)", ldap_err2string (rc)); - return rc; - } - - rc = ldap_install_tls (session->ls_conn); -#else - rc = ldap_start_tls_s (session->ls_conn, NULL, NULL); -#endif /* HAVE_LDAP_START_TLS */ - - if (rc != LDAP_SUCCESS) - { - debug ("<== do_start_tls (start TLS failed: %s)", ldap_err2string(rc)); - return rc; - } - - return LDAP_SUCCESS; -} -#endif - -/* - * Opens connection to an LDAP server - should only be called from search - * API. Other API that just needs access to configuration and schema should - * call do_init(). - * - * As with do_close(), this assumes ownership of sess. - * It also wants to own __config: is there a potential deadlock here? XXX - */ -static enum nss_status -do_open (void) -{ - struct ldap_config *cfg; - int usesasl; - char *bindarg; - enum nss_status stat; -#ifdef LDAP_OPT_NETWORK_TIMEOUT - struct timeval tv; -#endif -#ifdef LDAP_X_OPT_CONNECT_TIMEOUT - int timeout; -#endif - int rc; - - debug ("==> do_open"); - - /* Moved the head part of do_open() into do_init() */ - stat = do_init (); - if (stat != NSS_STATUS_SUCCESS) - { - debug ("<== do_open (session initialization failed)"); - return stat; - } - - assert (__session.ls_conn != NULL); - assert (__session.ls_config != NULL); - assert (__session.ls_state != LS_UNINITIALIZED); - - if (__session.ls_state == LS_CONNECTED_TO_DSA) - { - debug ("<== do_open (cached session)"); - return NSS_STATUS_SUCCESS; - } - - cfg = __session.ls_config; - -#if LDAP_SET_REBIND_PROC_ARGS == 3 - ldap_set_rebind_proc (__session.ls_conn, do_rebind, NULL); -#elif LDAP_SET_REBIND_PROC_ARGS == 2 - ldap_set_rebind_proc (__session.ls_conn, do_rebind); -#endif - - ldap_set_option (__session.ls_conn, LDAP_OPT_PROTOCOL_VERSION, - &cfg->ldc_version); - - ldap_set_option (__session.ls_conn, LDAP_OPT_DEREF, &cfg->ldc_deref); - - ldap_set_option (__session.ls_conn, LDAP_OPT_TIMELIMIT, - &cfg->ldc_timelimit); - -#ifdef LDAP_X_OPT_CONNECT_TIMEOUT - /* - * This is a new option in the Netscape SDK which sets - * the TCP connect timeout. For want of a better value, - * we use the bind_timelimit to control this. - */ - timeout = cfg->ldc_bind_timelimit * 1000; - ldap_set_option (__session.ls_conn, LDAP_X_OPT_CONNECT_TIMEOUT, &timeout); -#endif /* LDAP_X_OPT_CONNECT_TIMEOUT */ - -#ifdef LDAP_OPT_NETWORK_TIMEOUT - tv.tv_sec = cfg->ldc_bind_timelimit; - tv.tv_usec = 0; - ldap_set_option (__session.ls_conn, LDAP_OPT_NETWORK_TIMEOUT, &tv); -#endif /* LDAP_OPT_NETWORK_TIMEOUT */ - -#ifdef LDAP_OPT_REFERRALS - ldap_set_option (__session.ls_conn, LDAP_OPT_REFERRALS, - cfg->ldc_referrals ? LDAP_OPT_ON : LDAP_OPT_OFF); -#endif /* LDAP_OPT_REFERRALS */ - -#ifdef LDAP_OPT_RESTART - ldap_set_option (__session.ls_conn, LDAP_OPT_RESTART, - cfg->ldc_restart ? LDAP_OPT_ON : LDAP_OPT_OFF); -#endif /* LDAP_OPT_RESTART */ - -#if defined(HAVE_LDAP_START_TLS_S) || defined(HAVE_LDAP_START_TLS) - if (cfg->ldc_ssl_on == SSL_START_TLS) - { - int version; - - if (ldap_get_option - (__session.ls_conn, LDAP_OPT_PROTOCOL_VERSION, - &version) == LDAP_OPT_SUCCESS) - { - if (version < LDAP_VERSION3) - { - version = LDAP_VERSION3; - ldap_set_option (__session.ls_conn, LDAP_OPT_PROTOCOL_VERSION, - &version); - } - } - - /* set up SSL context */ - if (do_ssl_options (cfg) != LDAP_SUCCESS) - { - do_close (); - debug ("<== do_open (SSL setup failed)"); - return NSS_STATUS_UNAVAIL; - } - - stat = do_map_error (do_start_tls (&__session)); - if (stat == NSS_STATUS_SUCCESS) - { - debug (":== do_open (TLS startup succeeded)"); - } - else - { - do_close (); - debug ("<== do_open (TLS startup failed)"); - return stat; - } - } - else -#endif /* HAVE_LDAP_START_TLS_S || HAVE_LDAP_START_TLS */ - - /* - * If SSL is desired, then enable it. - */ - if (cfg->ldc_ssl_on == SSL_LDAPS) - { -#if defined(LDAP_OPT_X_TLS) - int tls = LDAP_OPT_X_TLS_HARD; - if (ldap_set_option (__session.ls_conn, LDAP_OPT_X_TLS, &tls) != - LDAP_SUCCESS) - { - do_close (); - debug ("<== do_open (TLS setup failed)"); - return NSS_STATUS_UNAVAIL; - } - - /* set up SSL context */ - if (do_ssl_options (cfg) != LDAP_SUCCESS) - { - do_close (); - debug ("<== do_open (SSL setup failed)"); - return NSS_STATUS_UNAVAIL; - } - -#elif defined(HAVE_LDAPSSL_CLIENT_INIT) - if (ldapssl_install_routines (__session.ls_conn) != LDAP_SUCCESS) - { - do_close (); - debug ("<== do_open (SSL setup failed)"); - return NSS_STATUS_UNAVAIL; - } -/* not in Solaris 9? */ -#ifndef LDAP_OPT_SSL -#define LDAP_OPT_SSL 0x0A -#endif - if (ldap_set_option (__session.ls_conn, LDAP_OPT_SSL, LDAP_OPT_ON) != - LDAP_SUCCESS) - { - do_close (); - debug ("<== do_open (SSL setup failed)"); - return NSS_STATUS_UNAVAIL; - } -#endif - } - - /* - * If we're running as root, let us bind as a special - * user, so we can fake shadow passwords. - * Thanks to Doug Nazar <nazard@dragoninc.on.ca> for this - * patch. - */ - if (__euid == 0 && cfg->ldc_rootbinddn != NULL) - { -#if defined(HAVE_LDAP_SASL_INTERACTIVE_BIND_S) && (defined(HAVE_SASL_H) || defined(HAVE_SASL_SASL_H)) - usesasl = cfg->ldc_rootusesasl; - bindarg = - cfg->ldc_rootusesasl ? cfg->ldc_rootsaslid : cfg->ldc_rootbindpw; -#else - usesasl = 0; - bindarg = cfg->ldc_rootbindpw; -#endif - - rc = do_bind (__session.ls_conn, - cfg->ldc_bind_timelimit, - cfg->ldc_rootbinddn, bindarg, usesasl); - } - else - { -#if defined(HAVE_LDAP_SASL_INTERACTIVE_BIND_S) && (defined(HAVE_SASL_H) || defined(HAVE_SASL_SASL_H)) - usesasl = cfg->ldc_usesasl; - bindarg = cfg->ldc_usesasl ? cfg->ldc_saslid : cfg->ldc_bindpw; -#else - usesasl = 0; - bindarg = cfg->ldc_bindpw; -#endif - - rc = do_bind (__session.ls_conn, - cfg->ldc_bind_timelimit, - cfg->ldc_binddn, - cfg->ldc_bindpw, usesasl); - } - - if (rc != LDAP_SUCCESS) - { - /* log actual LDAP error code */ - syslog (LOG_AUTHPRIV | LOG_INFO, - "nss_ldap: failed to bind to LDAP server %s: %s", - cfg->ldc_uris[__session.ls_current_uri], - ldap_err2string (rc)); - stat = do_map_error (rc); - do_close (); - debug ("<== do_open (failed to bind to DSA"); - } - else - { - do_set_sockopts (); - time (&__session.ls_timestamp); - __session.ls_state = LS_CONNECTED_TO_DSA; - stat = NSS_STATUS_SUCCESS; - debug ("<== do_open (session connected to DSA)"); - } - - return stat; -} - -#if defined HAVE_LDAP_START_TLS_S || (defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS)) -static int -do_ssl_options (struct ldap_config * cfg) -{ - int rc; - - debug ("==> do_ssl_options"); - -#ifdef LDAP_OPT_X_TLS_RANDOM_FILE - if (cfg->ldc_tls_randfile != NULL) - { - /* rand file */ - rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_RANDOM_FILE, - cfg->ldc_tls_randfile); - if (rc != LDAP_SUCCESS) - { - debug - ("<== do_ssl_options: Setting of LDAP_OPT_X_TLS_RANDOM_FILE failed"); - return LDAP_OPERATIONS_ERROR; - } - } -#endif /* LDAP_OPT_X_TLS_RANDOM_FILE */ - - if (cfg->ldc_tls_cacertfile != NULL) - { - /* ca cert file */ - rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CACERTFILE, - cfg->ldc_tls_cacertfile); - if (rc != LDAP_SUCCESS) - { - debug - ("<== do_ssl_options: Setting of LDAP_OPT_X_TLS_CACERTFILE failed"); - return LDAP_OPERATIONS_ERROR; - } - } - - if (cfg->ldc_tls_cacertdir != NULL) - { - /* ca cert directory */ - rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CACERTDIR, - cfg->ldc_tls_cacertdir); - if (rc != LDAP_SUCCESS) - { - debug - ("<== do_ssl_options: Setting of LDAP_OPT_X_TLS_CACERTDIR failed"); - return LDAP_OPERATIONS_ERROR; - } - } - - /* require cert? */ - if (cfg->ldc_tls_checkpeer > -1) - { - rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, - &cfg->ldc_tls_checkpeer); - if (rc != LDAP_SUCCESS) - { - debug - ("<== do_ssl_options: Setting of LDAP_OPT_X_TLS_REQUIRE_CERT failed"); - return LDAP_OPERATIONS_ERROR; - } - } - - if (cfg->ldc_tls_ciphers != NULL) - { - /* set cipher suite, certificate and private key: */ - rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CIPHER_SUITE, - cfg->ldc_tls_ciphers); - if (rc != LDAP_SUCCESS) - { - debug - ("<== do_ssl_options: Setting of LDAP_OPT_X_TLS_CIPHER_SUITE failed"); - return LDAP_OPERATIONS_ERROR; - } - } - - if (cfg->ldc_tls_cert != NULL) - { - rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CERTFILE, cfg->ldc_tls_cert); - if (rc != LDAP_SUCCESS) - { - debug - ("<== do_ssl_options: Setting of LDAP_OPT_X_TLS_CERTFILE failed"); - return LDAP_OPERATIONS_ERROR; - } - } - - if (cfg->ldc_tls_key != NULL) - { - rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_KEYFILE, cfg->ldc_tls_key); - if (rc != LDAP_SUCCESS) - { - debug - ("<== do_ssl_options: Setting of LDAP_OPT_X_TLS_KEYFILE failed"); - return LDAP_OPERATIONS_ERROR; - } - } - - debug ("<== do_ssl_options"); - - return LDAP_SUCCESS; -} -#endif - -/* - * This function initializes an enumeration context, acquiring - * the global mutex. - * - * It could be done from the default constructor, under Solaris, but we - * delay it until the setXXent() function is called. - */ -struct ent_context * -_nss_ldap_ent_context_init (struct ent_context ** pctx) -{ - struct ent_context *ctx; - - _nss_ldap_enter (); - - ctx = _nss_ldap_ent_context_init_locked (pctx); - - _nss_ldap_leave (); - - return ctx; -} - -/* - * Wrapper around ldap_result() to skip over search references - * and deal transparently with the last entry. - */ -static enum nss_status -do_result (struct ent_context * ctx, int all) -{ - int rc = LDAP_UNAVAILABLE; - enum nss_status stat = NSS_STATUS_TRYAGAIN; - struct timeval tv, *tvp; - - debug ("==> do_result"); - - if (__session.ls_config->ldc_timelimit == LDAP_NO_LIMIT) - { - tvp = NULL; - } - else - { - tv.tv_sec = __session.ls_config->ldc_timelimit; - tv.tv_usec = 0; - tvp = &tv; - } - - do - { - if (ctx->ec_res != NULL) - { - ldap_msgfree (ctx->ec_res); - ctx->ec_res = NULL; - } - - rc = - ldap_result (__session.ls_conn, ctx->ec_msgid, all, tvp, - &ctx->ec_res); - switch (rc) - { - case -1: - case 0: - if (ldap_get_option - (__session.ls_conn, LDAP_OPT_ERROR_NUMBER, &rc) != LDAP_SUCCESS) - { - rc = LDAP_UNAVAILABLE; - } - syslog (LOG_AUTHPRIV | LOG_ERR, "nss_ldap: could not get LDAP result - %s", - ldap_err2string (rc)); - stat = NSS_STATUS_UNAVAIL; - break; - case LDAP_RES_SEARCH_ENTRY: - stat = NSS_STATUS_SUCCESS; - break; - case LDAP_RES_SEARCH_RESULT: - if (all == LDAP_MSG_ALL) - { - /* we asked for the result chain, we got it. */ - stat = NSS_STATUS_SUCCESS; - } - else - { -#ifdef LDAP_MORE_RESULTS_TO_RETURN - int parserc; - /* NB: this frees ctx->ec_res */ - LDAPControl **resultControls = NULL; - - ctx->ec_cookie = NULL; - - parserc = - ldap_parse_result (__session.ls_conn, ctx->ec_res, &rc, NULL, - NULL, NULL, &resultControls, 1); - if (parserc != LDAP_SUCCESS - && parserc != LDAP_MORE_RESULTS_TO_RETURN) - { - stat = NSS_STATUS_UNAVAIL; - ldap_abandon (__session.ls_conn, ctx->ec_msgid); - syslog (LOG_AUTHPRIV | LOG_ERR, - "nss_ldap: could not get LDAP result - %s", - ldap_err2string (rc)); - } - else if (resultControls != NULL) - { - /* See if there are any more pages to come */ - parserc = ldap_parse_page_control (__session.ls_conn, - resultControls, NULL, - &(ctx->ec_cookie)); - ldap_controls_free (resultControls); - stat = NSS_STATUS_NOTFOUND; - } - else - { - stat = NSS_STATUS_NOTFOUND; - } -#else - stat = NSS_STATUS_NOTFOUND; -#endif /* LDAP_MORE_RESULTS_TO_RETURN */ - ctx->ec_res = NULL; - ctx->ec_msgid = -1; - } - break; - default: - stat = NSS_STATUS_UNAVAIL; - break; - } - } -#ifdef LDAP_RES_SEARCH_REFERENCE - while (rc == LDAP_RES_SEARCH_REFERENCE); -#else - while (0); -#endif /* LDAP_RES_SEARCH_REFERENCE */ - - if (stat == NSS_STATUS_SUCCESS) - time (&__session.ls_timestamp); - - debug ("<== do_result"); - - return stat; -} - -/* - * This function initializes an enumeration context. - * - * It could be done from the default constructor, under Solaris, but we - * delay it until the setXXent() function is called. - */ -struct ent_context * -_nss_ldap_ent_context_init_locked (struct ent_context ** pctx) -{ - struct ent_context *ctx; - - debug ("==> _nss_ldap_ent_context_init_locked"); - - ctx = *pctx; - - if (ctx == NULL) - { - ctx = (struct ent_context *) malloc (sizeof (*ctx)); - if (ctx == NULL) - { - debug ("<== _nss_ldap_ent_context_init_locked"); - return NULL; - } - *pctx = ctx; - } - else - { - if (ctx->ec_res != NULL) - { - ldap_msgfree (ctx->ec_res); - } - if (ctx->ec_cookie != NULL) - { - ber_bvfree (ctx->ec_cookie); - } - if (ctx->ec_msgid > -1 && do_result (ctx, LDAP_MSG_ONE) == NSS_STATUS_SUCCESS) - { - ldap_abandon (__session.ls_conn, ctx->ec_msgid); - } - } - - ctx->ec_cookie = NULL; - ctx->ec_res = NULL; - ctx->ec_msgid = -1; - ctx->ec_sd = NULL; - - LS_INIT (ctx->ec_state); - - debug ("<== _nss_ldap_ent_context_init_locked"); - - return ctx; -} - -/* - * Clears a given context; we require the caller - * to acquire the lock. - */ -void -_nss_ldap_ent_context_release (struct ent_context * ctx) -{ - debug ("==> _nss_ldap_ent_context_release"); - - if (ctx == NULL) - { - debug ("<== _nss_ldap_ent_context_release"); - return; - } - - if (ctx->ec_res != NULL) - { - ldap_msgfree (ctx->ec_res); - ctx->ec_res = NULL; - } - - /* - * Abandon the search if there were more results to fetch. - */ - if (ctx->ec_msgid > -1 && do_result (ctx, LDAP_MSG_ONE) == NSS_STATUS_SUCCESS) - { - ldap_abandon (__session.ls_conn, ctx->ec_msgid); - ctx->ec_msgid = -1; - } - - if (ctx->ec_cookie != NULL) - { - ber_bvfree (ctx->ec_cookie); - ctx->ec_cookie = NULL; - } - - ctx->ec_sd = NULL; - - LS_INIT (ctx->ec_state); - - if (_nss_ldap_test_config_flag (NSS_LDAP_FLAGS_CONNECT_POLICY_ONESHOT)) - { - do_close (); - } - - debug ("<== _nss_ldap_ent_context_release"); - - return; -} - -/* - * AND or OR a set of filters. - */ -static enum nss_status -do_aggregate_filter (const char **values, - enum ldap_args_types type, - const char *filterprot, char *bufptr, size_t buflen) -{ - enum nss_status stat; - const char **valueP; - - assert (buflen > sizeof ("(|)")); - - bufptr[0] = '('; - bufptr[1] = (type == LA_TYPE_STRING_LIST_AND) ? '&' : '|'; - - bufptr += 2; - buflen -= 2; - - for (valueP = values; *valueP != NULL; valueP++) - { - size_t len; - char filter[LDAP_FILT_MAXSIZ], escapedBuf[LDAP_FILT_MAXSIZ]; - - stat = - _nss_ldap_escape_string (*valueP, escapedBuf, sizeof (escapedBuf)); - if (stat != NSS_STATUS_SUCCESS) - return stat; - - snprintf (filter, sizeof (filter), filterprot, escapedBuf); - len = strlen (filter); - - if (buflen < len + 1 /* ')' */ ) - return NSS_STATUS_TRYAGAIN; - - memcpy (bufptr, filter, len); - bufptr[len] = '\0'; - bufptr += len; - buflen -= len; - } - - if (buflen < 2) - return NSS_STATUS_TRYAGAIN; - - *bufptr++ = ')'; - *bufptr++ = '\0'; - - buflen -= 2; - - return NSS_STATUS_SUCCESS; -} - -/* - * Do the necessary formatting to create a string filter. - */ -static enum nss_status -do_filter (const struct ldap_args * args, const char *filterprot, - struct ldap_service_search_descriptor * sd, char *userBuf, - size_t userBufSiz, char **dynamicUserBuf, const char **retFilter) -{ - char buf1[LDAP_FILT_MAXSIZ], buf2[LDAP_FILT_MAXSIZ]; - char *filterBufP, filterBuf[LDAP_FILT_MAXSIZ]; - size_t filterSiz; - enum nss_status stat = NSS_STATUS_SUCCESS; - - debug ("==> do_filter"); - - *dynamicUserBuf = NULL; - - if (args != NULL && args->la_type != LA_TYPE_NONE) - { - /* choose what to use for temporary storage */ - - if (sd != NULL && sd->lsd_filter != NULL) - { - filterBufP = filterBuf; - filterSiz = sizeof (filterBuf); - } - else - { - filterBufP = userBuf; - filterSiz = userBufSiz; - } - - switch (args->la_type) - { - case LA_TYPE_STRING: - stat = _nss_ldap_escape_string (args->la_arg1.la_string, buf1, - sizeof (buf1)); - if (stat != NSS_STATUS_SUCCESS) - break; - - snprintf (filterBufP, filterSiz, filterprot, buf1); - break; - case LA_TYPE_NUMBER: - snprintf (filterBufP, filterSiz, filterprot, - args->la_arg1.la_number); - break; - case LA_TYPE_STRING_AND_STRING: - stat = _nss_ldap_escape_string (args->la_arg1.la_string, buf1, - sizeof (buf1)); - if (stat != NSS_STATUS_SUCCESS) - break; - - stat = _nss_ldap_escape_string (args->la_arg2.la_string, buf2, - sizeof (buf2)); - if (stat != NSS_STATUS_SUCCESS) - break; - - snprintf (filterBufP, filterSiz, filterprot, buf1, buf2); - break; - case LA_TYPE_NUMBER_AND_STRING: - stat = _nss_ldap_escape_string (args->la_arg2.la_string, buf1, - sizeof (buf1)); - if (stat != NSS_STATUS_SUCCESS) - break; - - snprintf (filterBufP, filterSiz, filterprot, - args->la_arg1.la_number, buf1); - break; - case LA_TYPE_STRING_LIST_OR: - case LA_TYPE_STRING_LIST_AND: - do - { - stat = do_aggregate_filter (args->la_arg1.la_string_list, - args->la_type, - filterprot, filterBufP, filterSiz); - if (stat == NSS_STATUS_TRYAGAIN) - { - filterBufP = *dynamicUserBuf = realloc (*dynamicUserBuf, - 2 * filterSiz); - if (filterBufP == NULL) - return NSS_STATUS_UNAVAIL; - filterSiz *= 2; - } - } - while (stat == NSS_STATUS_TRYAGAIN); - break; - default: - return NSS_STATUS_UNAVAIL; - break; - } - - if (stat != NSS_STATUS_SUCCESS) - return stat; - - /* - * This code really needs to be cleaned up. - */ - if (sd != NULL && sd->lsd_filter != NULL) - { - size_t filterBufPLen = strlen (filterBufP); - - /* remove trailing bracket */ - if (filterBufP[filterBufPLen - 1] == ')') - filterBufP[filterBufPLen - 1] = '\0'; - - if (*dynamicUserBuf != NULL) - { - char *oldDynamicUserBuf = *dynamicUserBuf; - size_t dynamicUserBufSiz; - - dynamicUserBufSiz = filterBufPLen + strlen (sd->lsd_filter) + - sizeof ("())"); - *dynamicUserBuf = malloc (dynamicUserBufSiz); - if (*dynamicUserBuf == NULL) - { - free (oldDynamicUserBuf); - return NSS_STATUS_UNAVAIL; - } - - snprintf (*dynamicUserBuf, dynamicUserBufSiz, "%s(%s))", - filterBufP, sd->lsd_filter); - free (oldDynamicUserBuf); - } - else - { - snprintf (userBuf, userBufSiz, "%s(%s))", - filterBufP, sd->lsd_filter); - } - } - - if (*dynamicUserBuf != NULL) - *retFilter = *dynamicUserBuf; - else - *retFilter = userBuf; - } - else - { - /* no arguments, probably an enumeration filter */ - if (sd != NULL && sd->lsd_filter != NULL) - { - snprintf (userBuf, userBufSiz, "(&%s(%s))", - filterprot, sd->lsd_filter); - *retFilter = userBuf; - } - else - { - *retFilter = filterprot; - } - } - - debug (":== do_filter: %s", *retFilter); - - debug ("<== do_filter"); - - return NSS_STATUS_SUCCESS; -} - -/* - * Function to call either do_search() or do_search_s() with - * reconnection logic. - */ -static enum nss_status -do_with_reconnect (const char *base, int scope, - const char *filter, const char **attrs, int sizelimit, - void *private, search_func_t search_func) -{ - int rc = LDAP_UNAVAILABLE, tries = 0, backoff = 0; - int hard = 1, start_uri = 0, log = 0; - enum nss_status stat = NSS_STATUS_UNAVAIL; - int maxtries; - - debug ("==> do_with_reconnect"); - - /* caller must successfully call do_init() first */ - assert (__session.ls_config != NULL); - - maxtries = __session.ls_config->ldc_reconnect_maxconntries + - __session.ls_config->ldc_reconnect_tries; - - while (stat == NSS_STATUS_UNAVAIL && hard && tries < maxtries) - { - if (tries >= __session.ls_config->ldc_reconnect_maxconntries) - { - if (backoff == 0) - backoff = __session.ls_config->ldc_reconnect_sleeptime; - else if (backoff < __session.ls_config->ldc_reconnect_maxsleeptime) - backoff *= 2; - - syslog (LOG_AUTHPRIV | LOG_INFO, - "nss_ldap: reconnecting to LDAP server (sleeping %d seconds)...", - backoff); - (void) sleep (backoff); - } - else if (tries > 1) - { - /* Don't sleep, reconnect immediately. */ - syslog (LOG_AUTHPRIV | LOG_INFO, "nss_ldap: reconnecting to LDAP server..."); - } - - /* For each "try", attempt to connect to all specified URIs */ - start_uri = __session.ls_current_uri; - do - { - stat = do_open (); - if (stat == NSS_STATUS_SUCCESS) - { - stat = do_map_error (search_func (base, scope, filter, - attrs, sizelimit, private)); - } - if (stat != NSS_STATUS_UNAVAIL) - break; - - log++; - - /* test in case config file could not be read */ - if (__session.ls_config != NULL) - { - assert (__session.ls_config-> - ldc_uris[__session.ls_current_uri] != NULL); - - __session.ls_current_uri++; - - if (__session.ls_config->ldc_uris[__session.ls_current_uri] == - NULL) - __session.ls_current_uri = 0; - } - } - while (__session.ls_current_uri != start_uri); - - if (stat == NSS_STATUS_UNAVAIL) - { - do_close (); - - /* - * If a soft reconnect policy is specified, then do not - * try to reconnect to the LDAP server if it is down. - */ - if (__session.ls_config->ldc_reconnect_pol == LP_RECONNECT_SOFT) - hard = 0; - - /* - * If the file /lib/init/rw/libnss-ldap.bind_policy_soft exists, - * then ignore the actual bind_policy definition and use the - * soft semantics. This file should only exist during early - * boot and late shutdown, points at which the networking or - * the LDAP server itself are likely to be unavailable anyway. - */ - if (access("/lib/init/rw/libnss-ldap.bind_policy_soft",R_OK) == 0) - hard = 0; - - ++tries; - } - } - - switch (stat) - { - case NSS_STATUS_UNAVAIL: - syslog (LOG_AUTHPRIV | LOG_ERR, "nss_ldap: could not search LDAP server - %s", - ldap_err2string (rc)); - break; - case NSS_STATUS_TRYAGAIN: - syslog (LOG_AUTHPRIV | LOG_ERR, - "nss_ldap: could not %s %sconnect to LDAP server - %s", - hard ? "hard" : "soft", tries ? "re" : "", - ldap_err2string (rc)); - stat = NSS_STATUS_UNAVAIL; - break; - case NSS_STATUS_SUCCESS: - if (log) - { - char *uri = __session.ls_config->ldc_uris[__session.ls_current_uri]; - - if (uri == NULL) - uri = "(null)"; - - if (tries) - syslog (LOG_AUTHPRIV | LOG_INFO, - "nss_ldap: reconnected to LDAP server %s after %d attempt%s", - uri, tries, (tries == 1) ? "" : "s"); - else - syslog (LOG_AUTHPRIV | LOG_INFO, "nss_ldap: reconnected to LDAP server %s", uri); - } - time (&__session.ls_timestamp); - break; - default: - break; - } - - debug ("<== do_with_reconnect"); - return stat; -} - -/* - * Synchronous search function. Don't call this directly; - * always wrap calls to this with do_with_reconnect(), or, - * better still, use _nss_ldap_search_s(). - */ -static int -do_search_s (const char *base, int scope, - const char *filter, const char **attrs, int sizelimit, - LDAPMessage ** res) -{ - int rc; - struct timeval tv, *tvp; - - debug ("==> do_search_s"); - - ldap_set_option (__session.ls_conn, LDAP_OPT_SIZELIMIT, - (void *) &sizelimit); - - if (__session.ls_config->ldc_timelimit == LDAP_NO_LIMIT) - { - tvp = NULL; - } - else - { - tv.tv_sec = __session.ls_config->ldc_timelimit; - tv.tv_usec = 0; - tvp = &tv; - } - - rc = ldap_search_st (__session.ls_conn, base, scope, filter, - (char **) attrs, 0, tvp, res); - - debug ("<== do_search_s"); - - return rc; -} - -/* - * Asynchronous search function. Don't call this directly; - * always wrap calls to this with do_with_reconnect(), or, - * better still, use _nss_ldap_search(). - */ -static int -do_search (const char *base, int scope, - const char *filter, const char **attrs, int sizelimit, int *msgid) -{ - int rc; - LDAPControl *serverCtrls[2]; - LDAPControl **pServerCtrls; - - debug ("==> do_search"); - -#ifdef HAVE_LDAP_SEARCH_EXT - if (_nss_ldap_test_config_flag (NSS_LDAP_FLAGS_PAGED_RESULTS)) - { - rc = ldap_create_page_control (__session.ls_conn, - __session.ls_config->ldc_pagesize, - NULL, 0, &serverCtrls[0]); - if (rc != LDAP_SUCCESS) - return rc; - - serverCtrls[1] = NULL; - pServerCtrls = serverCtrls; - } - else - { - pServerCtrls = NULL; - } - - rc = ldap_search_ext (__session.ls_conn, base, scope, filter, - (char **) attrs, 0, pServerCtrls, NULL, - LDAP_NO_LIMIT, sizelimit, msgid); - - if (pServerCtrls != NULL) - { - ldap_control_free (serverCtrls[0]); - serverCtrls[0] = NULL; - } - -#else - ldap_set_option (__session.ls_conn, LDAP_OPT_SIZELIMIT, - (void *) &sizelimit); - - *msgid = ldap_search (__session.ls_conn, base, scope, filter, - (char **) attrs, 0); - if (*msgid < 0) - { - if (ldap_get_option - (__session.ls_conn, LDAP_OPT_ERROR_NUMBER, &rc) != LDAP_SUCCESS) - { - rc = LDAP_UNAVAILABLE; - } - } - else - { - rc = LDAP_SUCCESS; - } -#endif /* HAVE_LDAP_SEARCH_EXT */ - - debug ("<== do_search"); - - return rc; -} - -static void -do_map_errno (enum nss_status status, int *errnop) -{ - switch (status) - { - case NSS_STATUS_TRYAGAIN: - *errnop = ERANGE; - break; - case NSS_STATUS_NOTFOUND: - *errnop = ENOENT; - break; - case NSS_STATUS_SUCCESS: - default: - *errnop = 0; - } -} - -/* - * Tries parser function "parser" on entries, calling do_result() - * to retrieve them from the LDAP server until one parses - * correctly or there is an exceptional condition. - */ -static enum nss_status -do_parse (struct ent_context * ctx, void *result, char - *buffer, size_t buflen, int *errnop, parser_t parser) -{ - enum nss_status parseStat = NSS_STATUS_NOTFOUND; - - debug ("==> do_parse"); - - /* - * if ec_state.ls_info.ls_index is non-zero, then we don't collect another - * entry off the LDAP chain, and instead refeed the existing result to - * the parser. Once the parser has finished with it, it will return - * NSS_STATUS_NOTFOUND and reset the index to -1, at which point we'll retrieve - * another entry. - */ - do - { - enum nss_status resultStat = NSS_STATUS_SUCCESS; - - if (ctx->ec_state.ls_retry == 0 && - (ctx->ec_state.ls_type == LS_TYPE_KEY - || ctx->ec_state.ls_info.ls_index == -1)) - { - resultStat = do_result (ctx, LDAP_MSG_ONE); - } - - if (resultStat != NSS_STATUS_SUCCESS) - { - /* Could not get a result; bail */ - parseStat = resultStat; - break; - } - - /* - * We have an entry; now, try to parse it. - * - * If we do not parse the entry because of a schema - * violation, the parser should return NSS_STATUS_NOTFOUND. - * We'll keep on trying subsequent entries until we - * find one which is parseable, or exhaust avialable - * entries, whichever is first. - */ - parseStat = parser (ctx->ec_res, &ctx->ec_state, result, - buffer, buflen); - - /* hold onto the state if we're out of memory XXX */ - ctx->ec_state.ls_retry = (parseStat == NSS_STATUS_TRYAGAIN && buffer != NULL ? 1 : 0); - - /* free entry is we're moving on */ - if (ctx->ec_state.ls_retry == 0 && - (ctx->ec_state.ls_type == LS_TYPE_KEY - || ctx->ec_state.ls_info.ls_index == -1)) - { - /* we don't need the result anymore, ditch it. */ - ldap_msgfree (ctx->ec_res); - ctx->ec_res = NULL; - } - } - while (parseStat == NSS_STATUS_NOTFOUND); - - do_map_errno (parseStat, errnop); - - debug ("<== do_parse"); - - return parseStat; -} - -/* - * Parse, fetching reuslts from chain instead of server. - */ -static enum nss_status -do_parse_s (struct ent_context * ctx, void *result, char - *buffer, size_t buflen, int *errnop, parser_t parser) -{ - enum nss_status parseStat = NSS_STATUS_NOTFOUND; - LDAPMessage *e = NULL; - - debug ("==> do_parse_s"); - - /* - * if ec_state.ls_info.ls_index is non-zero, then we don't collect another - * entry off the LDAP chain, and instead refeed the existing result to - * the parser. Once the parser has finished with it, it will return - * NSS_STATUS_NOTFOUND and reset the index to -1, at which point we'll retrieve - * another entry. - */ - do - { - if (ctx->ec_state.ls_retry == 0 && - (ctx->ec_state.ls_type == LS_TYPE_KEY - || ctx->ec_state.ls_info.ls_index == -1)) - { - if (e == NULL) - e = ldap_first_entry (__session.ls_conn, ctx->ec_res); - else - e = ldap_next_entry (__session.ls_conn, e); - } - - if (e == NULL) - { - /* Could not get a result; bail */ - parseStat = NSS_STATUS_NOTFOUND; - break; - } - - /* - * We have an entry; now, try to parse it. - * - * If we do not parse the entry because of a schema - * violation, the parser should return NSS_STATUS_NOTFOUND. - * We'll keep on trying subsequent entries until we - * find one which is parseable, or exhaust avialable - * entries, whichever is first. - */ - parseStat = parser (e, &ctx->ec_state, result, buffer, buflen); - - /* hold onto the state if we're out of memory XXX */ - ctx->ec_state.ls_retry = (parseStat == NSS_STATUS_TRYAGAIN && buffer != NULL ? 1 : 0); - } - while (parseStat == NSS_STATUS_NOTFOUND); - - do_map_errno (parseStat, errnop); - - debug ("<== do_parse_s"); - - return parseStat; -} - -/* - * Read an entry from the directory, a la X.500. This is used - * for functions that need to retrieve attributes from a DN, - * such as the RFC2307bis group expansion function. - */ -enum nss_status -_nss_ldap_read (const char *dn, const char **attributes, LDAPMessage ** res) -{ - return do_with_reconnect (dn, LDAP_SCOPE_BASE, "(objectclass=*)", - attributes, 1, /* sizelimit */ res, - (search_func_t) do_search_s); -} - -/* - * Simple wrapper around ldap_get_values(). Requires that - * session is already established. - */ -char ** -_nss_ldap_get_values (LDAPMessage * e, const char *attr) -{ - if (__session.ls_state != LS_CONNECTED_TO_DSA) - { - return NULL; - } - assert (__session.ls_conn != NULL); - - return ldap_get_values (__session.ls_conn, e, (char *) attr); -} - -/* - * Simple wrapper around ldap_get_dn(). Requires that - * session is already established. - */ -char * -_nss_ldap_get_dn (LDAPMessage * e) -{ - if (__session.ls_state != LS_CONNECTED_TO_DSA) - { - return NULL; - } - assert (__session.ls_conn != NULL); - - return ldap_get_dn (__session.ls_conn, e); -} - -/* - * Simple wrapper around ldap_first_entry(). Requires that - * session is already established. - */ -LDAPMessage * -_nss_ldap_first_entry (LDAPMessage * res) -{ - if (__session.ls_state != LS_CONNECTED_TO_DSA) - { - return NULL; - } - assert (__session.ls_conn != NULL); - - return ldap_first_entry (__session.ls_conn, res); -} - -/* - * Simple wrapper around ldap_next_entry(). Requires that - * session is already established. - */ -LDAPMessage * -_nss_ldap_next_entry (LDAPMessage * res) -{ - if (__session.ls_state != LS_CONNECTED_TO_DSA) - { - return NULL; - } - assert (__session.ls_conn != NULL); - - return ldap_next_entry (__session.ls_conn, res); -} - -char * -_nss_ldap_first_attribute (LDAPMessage * entry, BerElement ** berptr) -{ - if (__session.ls_state != LS_CONNECTED_TO_DSA) - { - return NULL; - } - assert (__session.ls_conn != NULL); - - return ldap_first_attribute (__session.ls_conn, entry, berptr); -} - -char * -_nss_ldap_next_attribute (LDAPMessage * entry, BerElement * ber) -{ - if (__session.ls_state != LS_CONNECTED_TO_DSA) - { - return NULL; - } - assert (__session.ls_conn != NULL); - - return ldap_next_attribute (__session.ls_conn, entry, ber); -} - -/* - * The generic synchronous lookup cover function. - * Assumes caller holds lock. - */ -enum nss_status -_nss_ldap_search_s (const struct ldap_args * args, - const char *filterprot, enum ldap_map_selector sel, const - char **user_attrs, int sizelimit, LDAPMessage ** res) -{ - char sdBase[LDAP_FILT_MAXSIZ]; - const char *base = NULL; - char filterBuf[LDAP_FILT_MAXSIZ], *dynamicFilterBuf = NULL; - const char **attrs, *filter; - int scope; - enum nss_status stat; - struct ldap_service_search_descriptor *sd = NULL; - - debug ("==> _nss_ldap_search_s"); - - stat = do_init (); - if (stat != NSS_STATUS_SUCCESS) - { - debug ("<== _nss_ldap_search_s"); - return stat; - } - - /* Set some reasonable defaults. */ - base = __session.ls_config->ldc_base; - scope = __session.ls_config->ldc_scope; - attrs = NULL; - - if (args != NULL && args->la_base != NULL) - { - sel = LM_NONE; - base = args->la_base; - } - - if (sel < LM_NONE) - { - sd = __session.ls_config->ldc_sds[sel]; - next: - if (sd != NULL) - { - size_t len = strlen (sd->lsd_base); - if (sd->lsd_base[len - 1] == ',') - { - /* is relative */ - snprintf (sdBase, sizeof (sdBase), - "%s%s", sd->lsd_base, - __session.ls_config->ldc_base); - base = sdBase; - } - else - { - base = sd->lsd_base; - } - - if (sd->lsd_scope != -1) - { - scope = sd->lsd_scope; - } - } - attrs = __session.ls_config->ldc_attrtab[sel]; - } - - stat = - do_filter (args, filterprot, sd, filterBuf, sizeof (filterBuf), - &dynamicFilterBuf, &filter); - if (stat != NSS_STATUS_SUCCESS) - return stat; - - stat = do_with_reconnect (base, scope, filter, - (user_attrs != NULL) ? user_attrs : attrs, - sizelimit, res, (search_func_t) do_search_s); - - if (dynamicFilterBuf != NULL) - { - free (dynamicFilterBuf); - dynamicFilterBuf = NULL; - } - - /* If no entry was returned, try the next search descriptor. */ - if (sd != NULL && sd->lsd_next != NULL) - { - if (stat == NSS_STATUS_NOTFOUND || - (stat == NSS_STATUS_SUCCESS && - ldap_first_entry (__session.ls_conn, *res) == NULL)) - { - sd = sd->lsd_next; - goto next; - } - } - - debug ("<== _nss_ldap_search_s"); - - return stat; -} - -/* - * The generic lookup cover function (asynchronous). - * Assumes caller holds lock. - */ -static enum nss_status -_nss_ldap_search (const struct ldap_args * args, - const char *filterprot, enum ldap_map_selector sel, - const char **user_attrs, int sizelimit, int *msgid, - struct ldap_service_search_descriptor ** csd) -{ - char sdBase[LDAP_FILT_MAXSIZ]; - const char *base = NULL; - char filterBuf[LDAP_FILT_MAXSIZ], *dynamicFilterBuf = NULL; - const char **attrs, *filter; - int scope; - enum nss_status stat; - struct ldap_service_search_descriptor *sd = NULL; - - debug ("==> _nss_ldap_search"); - - *msgid = -1; - - stat = do_init (); - if (stat != NSS_STATUS_SUCCESS) - { - debug ("<== _nss_ldap_search"); - return stat; - } - - /* Set some reasonable defaults. */ - base = __session.ls_config->ldc_base; - scope = __session.ls_config->ldc_scope; - attrs = NULL; - - if (args != NULL && args->la_base != NULL) - { - sel = LM_NONE; - base = args->la_base; - } - - if (sel < LM_NONE || *csd != NULL) - { - /* - * If we were chasing multiple descriptors and there are none left, - * just quit with NSS_STATUS_NOTFOUND. - */ - if (*csd != NULL) - { - sd = (*csd)->lsd_next; - if (sd == NULL) - return NSS_STATUS_NOTFOUND; - } - else - { - sd = __session.ls_config->ldc_sds[sel]; - } - - *csd = sd; - - if (sd != NULL) - { - size_t len = strlen (sd->lsd_base); - if (sd->lsd_base[len - 1] == ',') - { - /* is relative */ - snprintf (sdBase, sizeof (sdBase), "%s%s", sd->lsd_base, - __session.ls_config->ldc_base); - base = sdBase; - } - else - { - base = sd->lsd_base; - } - - if (sd->lsd_scope != -1) - { - scope = sd->lsd_scope; - } - } - attrs = __session.ls_config->ldc_attrtab[sel]; - } - - stat = - do_filter (args, filterprot, sd, filterBuf, sizeof (filterBuf), - &dynamicFilterBuf, &filter); - if (stat != NSS_STATUS_SUCCESS) - return stat; - - stat = do_with_reconnect (base, scope, filter, - (user_attrs != NULL) ? user_attrs : attrs, - sizelimit, msgid, (search_func_t) do_search); - - if (dynamicFilterBuf != NULL) - free (dynamicFilterBuf); - - debug ("<== _nss_ldap_search"); - - return stat; -} - -#ifdef HAVE_LDAP_SEARCH_EXT -static enum nss_status -do_next_page (const struct ldap_args * args, - const char *filterprot, enum ldap_map_selector sel, int - sizelimit, int *msgid, struct berval *pCookie) -{ - char sdBase[LDAP_FILT_MAXSIZ]; - const char *base = NULL; - char filterBuf[LDAP_FILT_MAXSIZ], *dynamicFilterBuf = NULL; - const char **attrs, *filter; - int scope; - enum nss_status stat; - struct ldap_service_search_descriptor *sd = NULL; - LDAPControl *serverctrls[2] = { - NULL, NULL - }; - - /* Set some reasonable defaults. */ - base = __session.ls_config->ldc_base; - scope = __session.ls_config->ldc_scope; - attrs = NULL; - - if (args != NULL && args->la_base != NULL) - { - sel = LM_NONE; - base = args->la_base; - } - - if (sel < LM_NONE) - { - sd = __session.ls_config->ldc_sds[sel]; - if (sd != NULL) - { - size_t len = strlen (sd->lsd_base); - if (sd->lsd_base[len - 1] == ',') - { - snprintf (sdBase, sizeof (sdBase), "%s%s", sd->lsd_base, - __session.ls_config->ldc_base); - base = sdBase; - } - else - { - base = sd->lsd_base; - } - - if (sd->lsd_scope != -1) - { - scope = sd->lsd_scope; - } - } - attrs = __session.ls_config->ldc_attrtab[sel]; - } - - stat = - do_filter (args, filterprot, sd, filterBuf, sizeof (filterBuf), - &dynamicFilterBuf, &filter); - if (stat != NSS_STATUS_SUCCESS) - { - return stat; - } - - stat = - ldap_create_page_control (__session.ls_conn, - __session.ls_config->ldc_pagesize, - pCookie, 0, &serverctrls[0]); - if (stat != LDAP_SUCCESS) - { - if (dynamicFilterBuf != NULL) - free (dynamicFilterBuf); - return NSS_STATUS_UNAVAIL; - } - - stat = - ldap_search_ext (__session.ls_conn, base, - __session.ls_config->ldc_scope, - filter, - (char **) attrs, 0, serverctrls, NULL, LDAP_NO_LIMIT, - sizelimit, msgid); - - ldap_control_free (serverctrls[0]); - if (dynamicFilterBuf != NULL) - free (dynamicFilterBuf); - - return (*msgid < 0) ? NSS_STATUS_UNAVAIL : NSS_STATUS_SUCCESS; -} -#endif /* HAVE_LDAP_SEARCH_EXT */ - -/* - * General entry point for enumeration routines. - * This should really use the asynchronous LDAP search API to avoid - * pulling down all the entries at once, particularly if the - * enumeration is not completed. - * Locks mutex. - */ -enum nss_status -_nss_ldap_getent (struct ent_context ** ctx, - void *result, char *buffer, size_t buflen, - int *errnop, const char *filterprot, - enum ldap_map_selector sel, parser_t parser) -{ - enum nss_status status; - - /* - * we need to lock here as the context may not be thread-specific - * data (under glibc, for example). Maybe we should make the lock part - * of the context. - */ - - _nss_ldap_enter (); - status = _nss_ldap_getent_ex (NULL, ctx, result, - buffer, buflen, - errnop, filterprot, sel, NULL, parser); - _nss_ldap_leave (); - - return status; -} - -/* - * Internal entry point for enumeration routines. - * Caller holds global mutex - */ -enum nss_status -_nss_ldap_getent_ex (struct ldap_args * args, - struct ent_context ** ctx, void *result, - char *buffer, size_t buflen, int *errnop, - const char *filterprot, - enum ldap_map_selector sel, - const char **user_attrs, parser_t parser) -{ - enum nss_status stat = NSS_STATUS_SUCCESS; - - debug ("==> _nss_ldap_getent_ex"); - - if (*ctx == NULL || (*ctx)->ec_msgid < 0) - { - /* - * implicitly call setent() if this is the first time - * or there is no active search - */ - if (_nss_ldap_ent_context_init_locked (ctx) == NULL) - { - debug ("<== _nss_ldap_getent_ex"); - return NSS_STATUS_UNAVAIL; - } - } - -next: - /* - * If ctx->ec_msgid < 0, then we haven't searched yet. Let's do it! - */ - if ((*ctx)->ec_msgid < 0) - { - int msgid; - - stat = _nss_ldap_search (args, filterprot, sel, user_attrs, - LDAP_NO_LIMIT, &msgid, &(*ctx)->ec_sd); - if (stat != NSS_STATUS_SUCCESS) - { - debug ("<== _nss_ldap_getent_ex"); - return stat; - } - - (*ctx)->ec_msgid = msgid; - } - - stat = do_parse (*ctx, result, buffer, buflen, errnop, parser); - -#ifdef HAVE_LDAP_SEARCH_EXT - if (stat == NSS_STATUS_NOTFOUND) - { - /* Is there another page of results? */ - if ((*ctx)->ec_cookie != NULL && (*ctx)->ec_cookie->bv_len != 0) - { - int msgid; - - stat = - do_next_page (NULL, filterprot, sel, LDAP_NO_LIMIT, &msgid, - (*ctx)->ec_cookie); - if (stat != NSS_STATUS_SUCCESS) - { - debug ("<== _nss_ldap_getent_ex"); - return stat; - } - (*ctx)->ec_msgid = msgid; - stat = do_parse (*ctx, result, buffer, buflen, errnop, parser); - } - } -#endif /* HAVE_LDAP_SEARCH_EXT */ - - if (stat == NSS_STATUS_NOTFOUND && (*ctx)->ec_sd != NULL) - { - (*ctx)->ec_msgid = -1; - goto next; - } - - debug ("<== _nss_ldap_getent_ex"); - - return stat; -} - -/* - * General match function. - * Locks mutex. - */ -enum nss_status -_nss_ldap_getbyname (struct ldap_args * args, - void *result, char *buffer, size_t buflen, int - *errnop, const char *filterprot, - enum ldap_map_selector sel, parser_t parser) -{ - enum nss_status stat = NSS_STATUS_NOTFOUND; - struct ent_context ctx; - - _nss_ldap_enter (); - - debug ("==> _nss_ldap_getbyname"); - - ctx.ec_msgid = -1; - ctx.ec_cookie = NULL; - - stat = _nss_ldap_search_s (args, filterprot, sel, NULL, 1, &ctx.ec_res); - if (stat != NSS_STATUS_SUCCESS) - { - _nss_ldap_leave (); - debug ("<== _nss_ldap_getbyname"); - return stat; - } - - /* - * we pass this along for the benefit of the services parser, - * which uses it to figure out which protocol we really wanted. - * we only pass the second argument along, as that's what we need - * in services. - */ - LS_INIT (ctx.ec_state); - ctx.ec_state.ls_type = LS_TYPE_KEY; - ctx.ec_state.ls_info.ls_key = args->la_arg2.la_string; - - stat = do_parse_s (&ctx, result, buffer, buflen, errnop, parser); - - _nss_ldap_ent_context_release (&ctx); - - debug ("<== _nss_ldap_getbyname"); - - /* moved unlock here to avoid race condition bug #49 */ - _nss_ldap_leave (); - - return stat; -} - -static int NEW_do_parse_s(struct ent_context *ctx,FILE *fp,NEWparser_t parser) -{ - int parseStat=NSLCD_RESULT_NOTFOUND; - LDAPMessage *e=NULL; - /* - * if ec_state.ls_info.ls_index is non-zero, then we don't collect another - * entry off the LDAP chain, and instead refeed the existing result to - * the parser. Once the parser has finished with it, it will return - * NSS_STATUS_NOTFOUND and reset the index to -1, at which point we'll retrieve - * another entry. - */ - do - { - if (ctx->ec_state.ls_retry == 0 && - (ctx->ec_state.ls_type == LS_TYPE_KEY - || ctx->ec_state.ls_info.ls_index == -1)) - { - if (e == NULL) - e = ldap_first_entry (__session.ls_conn, ctx->ec_res); - else - e = ldap_next_entry (__session.ls_conn, e); - } - if (e == NULL) - { - /* Could not get a result; bail */ - parseStat=NSLCD_RESULT_NOTFOUND; - break; - } - /* - * We have an entry; now, try to parse it. - * - * If we do not parse the entry because of a schema - * violation, the parser should return NSS_STATUS_NOTFOUND. - * We'll keep on trying subsequent entries until we - * find one which is parseable, or exhaust avialable - * entries, whichever is first. - */ - parseStat=parser(e,&ctx->ec_state,fp); - /* hold onto the state if we're out of memory XXX */ - ctx->ec_state.ls_retry=0; - } - while (parseStat==NSLCD_RESULT_NOTFOUND); - return parseStat; -} - - -int _nss_ldap_searchbyname( - struct ldap_args *args,const char *filterprot, - enum ldap_map_selector sel,FILE *fp,NEWparser_t parser) -{ - int stat; - struct ent_context ctx; - int32_t tmpint32; - - _nss_ldap_enter(); - - ctx.ec_msgid=-1; - ctx.ec_cookie=NULL; - - stat=nss2nslcd(_nss_ldap_search_s(args,filterprot,sel,NULL,1,&ctx.ec_res)); - /* write the result code */ - WRITE_INT32(fp,stat); - /* bail on nothing found */ - if (stat!=NSLCD_RESULT_SUCCESS) - { - _nss_ldap_leave(); - return 1; - } - /* - * we pass this along for the benefit of the services parser, - * which uses it to figure out which protocol we really wanted. - * we only pass the second argument along, as that's what we need - * in services. - */ - LS_INIT(ctx.ec_state); - ctx.ec_state.ls_type=LS_TYPE_KEY; - ctx.ec_state.ls_info.ls_key=args->la_arg2.la_string; - /* call the parser for the result */ - stat=NEW_do_parse_s(&ctx,fp,parser); - - _nss_ldap_ent_context_release(&ctx); - - /* moved unlock here to avoid race condition bug #49 */ - _nss_ldap_leave(); - - return stat; -} - -/* - * These functions are called from within the parser, where it is assumed - * to be safe to use the connection and the respective message. - */ - -/* - * Assign all values, bar omitvalue (if not NULL), to *valptr. - */ -enum nss_status -_nss_ldap_assign_attrvals (LDAPMessage * e, - const char *attr, const char *omitvalue, - char ***valptr, char **pbuffer, size_t * - pbuflen, size_t * pvalcount) -{ - char **vals; - char **valiter; - int valcount; - char **p = NULL; - - register int buflen = *pbuflen; - register char *buffer = *pbuffer; - - if (pvalcount != NULL) - { - *pvalcount = 0; - } - - if (__session.ls_conn == NULL) - { - return NSS_STATUS_UNAVAIL; - } - - vals = ldap_get_values (__session.ls_conn, e, (char *) attr); - - valcount = (vals == NULL) ? 0 : ldap_count_values (vals); - if (bytesleft (buffer, buflen, char *) < (valcount + 1) * sizeof (char *)) - { - ldap_value_free (vals); - return NSS_STATUS_TRYAGAIN; - } - - align (buffer, buflen, char *); - p = *valptr = (char **) buffer; - - buffer += (valcount + 1) * sizeof (char *); - buflen -= (valcount + 1) * sizeof (char *); - - if (valcount == 0) - { - *p = NULL; - *pbuffer = buffer; - *pbuflen = buflen; - return NSS_STATUS_SUCCESS; - } - - valiter = vals; - - while (*valiter != NULL) - { - int vallen; - char *elt = NULL; - - if (omitvalue != NULL && strcmp (*valiter, omitvalue) == 0) - { - valcount--; - } - else - { - vallen = strlen (*valiter); - if (buflen < (size_t) (vallen + 1)) - { - ldap_value_free (vals); - return NSS_STATUS_TRYAGAIN; - } - - /* copy this value into the next block of buffer space */ - elt = buffer; - buffer += vallen + 1; - buflen -= vallen + 1; - - strncpy (elt, *valiter, vallen); - elt[vallen] = '\0'; - *p = elt; - p++; - } - valiter++; - } - - *p = NULL; - *pbuffer = buffer; - *pbuflen = buflen; - - if (pvalcount != NULL) - { - *pvalcount = valcount; - } - - ldap_value_free (vals); - return NSS_STATUS_SUCCESS; -} - -int _nss_ldap_write_attrvals(FILE *fp,LDAPMessage *e,const char *attr) -{ - char **vals; - int valcount; - int i; - int32_t tmpint32; - /* log */ - log_log(LOG_DEBUG,"_nss_ldap_write_attrvals(%s)",attr); - /* check if we have a connection */ - if (__session.ls_conn==NULL) - return NSLCD_RESULT_UNAVAIL; - /* get the values and the number of values */ - vals=ldap_get_values(__session.ls_conn,e,(char *)attr); - valcount=(vals==NULL)?0:ldap_count_values(vals); - /* write number of entries */ - WRITE_INT32(fp,valcount); - /* write the entries themselves */ - for (i=0;i<valcount;i++) - { - WRITE_STRING(fp,vals[i]); - } - if (vals!=NULL) - ldap_value_free(vals); - return NSLCD_RESULT_SUCCESS; -} - -/* Assign a single value to *valptr. */ -enum nss_status -_nss_ldap_assign_attrval (LDAPMessage * e, - const char *attr, char **valptr, char **buffer, - size_t * buflen) -{ - char **vals; - int vallen; - const char *ovr, *def; - - ovr = OV (attr); - if (ovr != NULL) - { - vallen = strlen (ovr); - if (*buflen < (size_t) (vallen + 1)) - { - return NSS_STATUS_TRYAGAIN; - } - - *valptr = *buffer; - - strncpy (*valptr, ovr, vallen); - (*valptr)[vallen] = '\0'; - - *buffer += vallen + 1; - *buflen -= vallen + 1; - - return NSS_STATUS_SUCCESS; - } - - if (__session.ls_conn == NULL) - { - return NSS_STATUS_UNAVAIL; - } - - vals = ldap_get_values (__session.ls_conn, e, (char *) attr); - if (vals == NULL) - { - def = DF (attr); - if (def != NULL) - { - vallen = strlen (def); - if (*buflen < (size_t) (vallen + 1)) - { - return NSS_STATUS_TRYAGAIN; - } - - *valptr = *buffer; - - strncpy (*valptr, def, vallen); - (*valptr)[vallen] = '\0'; - - *buffer += vallen + 1; - *buflen -= vallen + 1; - - return NSS_STATUS_SUCCESS; - } - else - { - return NSS_STATUS_NOTFOUND; - } - } - - vallen = strlen (*vals); - if (*buflen < (size_t) (vallen + 1)) - { - ldap_value_free (vals); - return NSS_STATUS_TRYAGAIN; - } - - *valptr = *buffer; - - strncpy (*valptr, *vals, vallen); - (*valptr)[vallen] = '\0'; - - *buffer += vallen + 1; - *buflen -= vallen + 1; - - ldap_value_free (vals); - - return NSS_STATUS_SUCCESS; -} - -const char * -_nss_ldap_locate_userpassword (char **vals) -{ - const char *token = NULL; - size_t token_length = 0; - char **valiter; - const char *pwd = NULL; - - if (__config != NULL) - { - switch (__config->ldc_password_type) - { - case LU_RFC2307_USERPASSWORD: - token = "{CRYPT}"; - token_length = sizeof ("{CRYPT}") - 1; - break; - case LU_RFC3112_AUTHPASSWORD: - token = "CRYPT$"; - token_length = sizeof ("CRYPT$") - 1; - break; - case LU_OTHER_PASSWORD: - break; - } - } - - if (vals != NULL) - { - for (valiter = vals; *valiter != NULL; valiter++) - { - if (token_length == 0 || - strncasecmp (*valiter, token, token_length) == 0) - { - pwd = *valiter; - break; - } - } - } - - if (pwd == NULL) - pwd = "*"; - else - pwd += token_length; - - return pwd; -} - -/* - * Assign a single value to *valptr, after examining userPassword for - * a syntactically suitable value. - */ -enum nss_status -_nss_ldap_assign_userpassword (LDAPMessage * e, - const char *attr, char **valptr, - char **buffer, size_t * buflen) -{ - char **vals; - const char *pwd; - int vallen; - - debug ("==> _nss_ldap_assign_userpassword"); - - if (__session.ls_conn == NULL) - { - return NSS_STATUS_UNAVAIL; - } - - vals = ldap_get_values (__session.ls_conn, e, (char *) attr); - pwd = _nss_ldap_locate_userpassword (vals); - - vallen = strlen (pwd); - - if (*buflen < (size_t) (vallen + 1)) - { - if (vals != NULL) - { - ldap_value_free (vals); - } - debug ("<== _nss_ldap_assign_userpassword"); - return NSS_STATUS_TRYAGAIN; - } - - *valptr = *buffer; - - strncpy (*valptr, pwd, vallen); - (*valptr)[vallen] = '\0'; - - *buffer += vallen + 1; - *buflen -= vallen + 1; - - if (vals != NULL) - { - ldap_value_free (vals); - } - - debug ("<== _nss_ldap_assign_userpassword"); - - return NSS_STATUS_SUCCESS; -} - -enum nss_status -_nss_ldap_oc_check (LDAPMessage * e, const char *oc) -{ - char **vals, **valiter; - enum nss_status ret = NSS_STATUS_NOTFOUND; - - if (__session.ls_conn == NULL) - { - return NSS_STATUS_UNAVAIL; - } - - vals = ldap_get_values (__session.ls_conn, e, AT (objectClass)); - if (vals != NULL) - { - for (valiter = vals; *valiter != NULL; valiter++) - { - if (strcasecmp (*valiter, oc) == 0) - { - ret = NSS_STATUS_SUCCESS; - break; - } - } - } - - if (vals != NULL) - { - ldap_value_free (vals); - } - - return ret; -} - -#ifdef HAVE_SHADOW_H -int -_nss_ldap_shadow_date (const char *val) -{ - int date; - - if (__config->ldc_shadow_type == LS_AD_SHADOW) - { - date = atoll (val) / 864000000000LL - 134774LL; - date = (date > 99999) ? 99999 : date; - } - else - { - date = atol (val); - } - - return date; -} - -void -_nss_ldap_shadow_handle_flag (struct spwd *sp) -{ - if (__config->ldc_shadow_type == LS_AD_SHADOW) - { - if (sp->sp_flag & UF_DONT_EXPIRE_PASSWD) - sp->sp_max = 99999; - sp->sp_flag = 0; - } -} -#endif /* HAVE_SHADOW_H */ - -const char * -_nss_ldap_map_at (enum ldap_map_selector sel, const char *attribute) -{ - const char *mapped = NULL; - enum nss_status stat; - - stat = _nss_ldap_map_get (__config, sel, MAP_ATTRIBUTE, attribute, &mapped); - - return (stat == NSS_STATUS_SUCCESS) ? mapped : attribute; -} - -const char * -_nss_ldap_unmap_at (enum ldap_map_selector sel, const char *attribute) -{ - const char *mapped = NULL; - enum nss_status stat; - - stat = _nss_ldap_map_get (__config, sel, MAP_ATTRIBUTE_REVERSE, attribute, &mapped); - - return (stat == NSS_STATUS_SUCCESS) ? mapped : attribute; -} - -const char * -_nss_ldap_map_oc (enum ldap_map_selector sel, const char *objectclass) -{ - const char *mapped = NULL; - enum nss_status stat; - - stat = _nss_ldap_map_get (__config, sel, MAP_OBJECTCLASS, objectclass, &mapped); - - return (stat == NSS_STATUS_SUCCESS) ? mapped : objectclass; -} - -const char * -_nss_ldap_unmap_oc (enum ldap_map_selector sel, const char *objectclass) -{ - const char *mapped = NULL; - enum nss_status stat; - - stat = _nss_ldap_map_get (__config, sel, MAP_OBJECTCLASS_REVERSE, objectclass, &mapped); - - return (stat == NSS_STATUS_SUCCESS) ? mapped : objectclass; -} - -const char * -_nss_ldap_map_ov (const char *attribute) -{ - const char *value = NULL; - - _nss_ldap_map_get (__config, LM_NONE, MAP_OVERRIDE, attribute, &value); - - return value; -} - -const char * -_nss_ldap_map_df (const char *attribute) -{ - const char *value = NULL; - - _nss_ldap_map_get (__config, LM_NONE, MAP_DEFAULT, attribute, &value); - - return value; -} - -enum nss_status -_nss_ldap_map_put (struct ldap_config * config, - enum ldap_map_selector sel, - enum ldap_map_type type, - const char *from, - const char *to) -{ - struct ldap_datum key, val; - void **map; - enum nss_status stat; - - switch (type) - { - case MAP_ATTRIBUTE: - /* special handling for attribute mapping */ if (strcmp - (from, - "userPassword") == 0) - { - if (strcasecmp (to, "userPassword") == 0) - config->ldc_password_type = LU_RFC2307_USERPASSWORD; - else if (strcasecmp (to, "authPassword") == 0) - config->ldc_password_type = LU_RFC3112_AUTHPASSWORD; - else - config->ldc_password_type = LU_OTHER_PASSWORD; - } - else if (strcmp (from, "shadowLastChange") == 0) - { - if (strcasecmp (to, "shadowLastChange") == 0) - config->ldc_shadow_type = LS_RFC2307_SHADOW; - else if (strcasecmp (to, "pwdLastSet") == 0) - config->ldc_shadow_type = LS_AD_SHADOW; - else - config->ldc_shadow_type = LS_OTHER_SHADOW; - } - break; - case MAP_OBJECTCLASS: - case MAP_OVERRIDE: - case MAP_DEFAULT: - break; - default: - return NSS_STATUS_NOTFOUND; - break; - } - - assert (sel <= LM_NONE); - map = &config->ldc_maps[sel][type]; - assert (*map != NULL); - - NSS_LDAP_DATUM_ZERO (&key); - key.data = (void *) from; - key.size = strlen (from) + 1; - - NSS_LDAP_DATUM_ZERO (&val); - val.data = (void *) to; - val.size = strlen (to) + 1; - - stat = _nss_ldap_db_put (*map, NSS_LDAP_DB_NORMALIZE_CASE, &key, &val); - if (stat == NSS_STATUS_SUCCESS && - (type == MAP_ATTRIBUTE || type == MAP_OBJECTCLASS)) - { - type = (type == MAP_ATTRIBUTE) ? MAP_ATTRIBUTE_REVERSE : MAP_OBJECTCLASS_REVERSE; - map = &config->ldc_maps[sel][type]; - - stat = _nss_ldap_db_put (*map, NSS_LDAP_DB_NORMALIZE_CASE, &val, &key); - } - - return stat; -} - -enum nss_status -_nss_ldap_map_get (struct ldap_config * config, - enum ldap_map_selector sel, - enum ldap_map_type type, - const char *from, const char **to) -{ - struct ldap_datum key, val; - void *map; - enum nss_status stat; - - if (config == NULL || sel > LM_NONE || type > MAP_MAX) - { - return NSS_STATUS_NOTFOUND; - } - - map = config->ldc_maps[sel][type]; - assert (map != NULL); - - NSS_LDAP_DATUM_ZERO (&key); - key.data = from; - key.size = strlen (from) + 1; - - NSS_LDAP_DATUM_ZERO (&val); - - stat = _nss_ldap_db_get (map, NSS_LDAP_DB_NORMALIZE_CASE, &key, &val); - if (stat == NSS_STATUS_NOTFOUND && sel != LM_NONE) - { - map = config->ldc_maps[LM_NONE][type]; - assert (map != NULL); - stat = _nss_ldap_db_get (map, NSS_LDAP_DB_NORMALIZE_CASE, &key, &val); - } - - if (stat == NSS_STATUS_SUCCESS) - *to = (char *) val.data; - else - *to = NULL; - - return stat; -} - -/* - * Proxy bind support for AIX. Very simple, but should do - * the job. - */ - -struct ldap_proxy_bind_args -{ - char *binddn; - const char *bindpw; -}; - - -#if LDAP_SET_REBIND_PROC_ARGS < 3 -static struct ldap_proxy_bind_args __proxy_args = { NULL, NULL }; -#endif - -#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) -#if LDAP_SET_REBIND_PROC_ARGS == 3 -static int -do_proxy_rebind (LDAP * ld, LDAP_CONST char *url, ber_tag_t request, - ber_int_t msgid, void *arg) -#else -static int -do_proxy_rebind (LDAP * ld, LDAP_CONST char *url, int request, - ber_int_t msgid) -#endif -{ - int timelimit; -#if LDAP_SET_REBIND_PROC_ARGS == 3 - struct ldap_proxy_bind_args *who = (struct ldap_proxy_bind_args *) arg; -#else - struct ldap_proxy_bind_args *who = &__proxy_args; -#endif - - timelimit = __session.ls_config->ldc_bind_timelimit; - - return do_bind (ld, timelimit, who->binddn, who->bindpw, 0); -} -#else -#if LDAP_SET_REBIND_PROC_ARGS == 3 -static int -do_proxy_rebind (LDAP * ld, char **whop, char **credp, int *methodp, - int freeit, void *arg) -#elif LDAP_SET_REBIND_PROC_ARGS == 2 -static int -do_proxy_rebind (LDAP * ld, char **whop, char **credp, int *methodp, - int freeit) -#endif -{ -#if LDAP_SET_REBIND_PROC_ARGS == 3 - struct ldap_proxy_bind_args *who = (struct ldap_proxy_bind_args *) arg; -#else - struct ldap_proxy_bind_args *who = &__proxy_args; -#endif - if (freeit) - { - if (*whop != NULL) - free (*whop); - if (*credp != NULL) - free (*credp); - } - - *whop = who->binddn ? strdup (who->binddn) : NULL; - *credp = who->bindpw ? strdup (who->bindpw) : NULL; - - *methodp = LDAP_AUTH_SIMPLE; - - return LDAP_SUCCESS; -} -#endif - -enum nss_status -_nss_ldap_proxy_bind (const char *user, const char *password) -{ - struct ldap_args args; - LDAPMessage *res, *e; - enum nss_status stat; - int rc; -#if LDAP_SET_REBIND_PROC_ARGS == 3 - struct ldap_proxy_bind_args proxy_args_buf; - struct ldap_proxy_bind_args *proxy_args = &proxy_args_buf; -#else - struct ldap_proxy_bind_args *proxy_args = &__proxy_args; -#endif - - debug ("==> _nss_ldap_proxy_bind"); - - LA_INIT (args); - LA_TYPE (args) = LA_TYPE_STRING; - LA_STRING (args) = user; - - /* - * Binding with an empty password will always work, so don't let - * the user in if they try that. - */ - if (password == NULL || password[0] == '\0') - { - debug ("<== _nss_ldap_proxy_bind (empty password not permitted)"); - /* XXX overload */ - return NSS_STATUS_TRYAGAIN; - } - - _nss_ldap_enter (); - - stat = _nss_ldap_search_s (&args, _nss_ldap_filt_getpwnam, - LM_PASSWD, NULL, 1, &res); - if (stat == NSS_STATUS_SUCCESS) - { - e = _nss_ldap_first_entry (res); - if (e != NULL) - { - proxy_args->binddn = _nss_ldap_get_dn (e); - proxy_args->bindpw = password; - - if (proxy_args->binddn != NULL) - { - /* Use our special rebind procedure. */ -#if LDAP_SET_REBIND_PROC_ARGS == 3 - ldap_set_rebind_proc (__session.ls_conn, do_proxy_rebind, NULL); -#elif LDAP_SET_REBIND_PROC_ARGS == 2 - ldap_set_rebind_proc (__session.ls_conn, do_proxy_rebind); -#endif - - debug (":== _nss_ldap_proxy_bind: %s", proxy_args->binddn); - - rc = do_bind (__session.ls_conn, - __session.ls_config->ldc_bind_timelimit, - proxy_args->binddn, proxy_args->bindpw, 0); - switch (rc) - { - case LDAP_INVALID_CREDENTIALS: - /* XXX overload */ - stat = NSS_STATUS_TRYAGAIN; - break; - case LDAP_NO_SUCH_OBJECT: - stat = NSS_STATUS_NOTFOUND; - break; - case LDAP_SUCCESS: - stat = NSS_STATUS_SUCCESS; - break; - default: - stat = NSS_STATUS_UNAVAIL; - break; - } - /* - * Close the connection, don't want to continue - * being bound as this user or using this rebind proc. - */ - do_close (); - ldap_memfree (proxy_args->binddn); - } - else - { - stat = NSS_STATUS_NOTFOUND; - } - proxy_args->binddn = NULL; - proxy_args->bindpw = NULL; - } - else - { - stat = NSS_STATUS_NOTFOUND; - } - ldap_msgfree (res); - } - - _nss_ldap_leave (); - - debug ("<== _nss_ldap_proxy_bind"); - - return stat; -} - -const char ** -_nss_ldap_get_attributes (enum ldap_map_selector sel) -{ - const char **attrs = NULL; - - debug ("==> _nss_ldap_get_attributes"); - - if (sel < LM_NONE) - { - if (do_init () != NSS_STATUS_SUCCESS) - { - debug ("<== _nss_ldap_get_attributes (init failed)"); - return NULL; - } - - attrs = __session.ls_config->ldc_attrtab[sel]; - } - - debug ("<== _nss_ldap_get_attributes"); - - return attrs; -} - -int -_nss_ldap_test_config_flag (unsigned int flag) -{ - if (__config != NULL && (__config->ldc_flags & flag) != 0) - return 1; - - return 0; -} - -int -_nss_ldap_test_initgroups_ignoreuser (const char *user) -{ - char **p; - - if (__config == NULL) - return 0; - - if (__config->ldc_initgroups_ignoreusers == NULL) - return 0; - - for (p = __config->ldc_initgroups_ignoreusers; *p != NULL; p++) - { - if (strcmp (*p, user) == 0) - return 1; - } - - return 0; -} diff --git a/server/ldap-nss.h b/server/ldap-nss.h deleted file mode 100644 index b59d774..0000000 --- a/server/ldap-nss.h +++ /dev/null @@ -1,611 +0,0 @@ -/* - ldap-nss.c - main file for NSS interface - This file was part of the nss_ldap library which has been - forked into the nss-ldapd library. - - Copyright (C) 1997-2005 Luke Howard - Copyright (C) 2006 West Consulting - Copyright (C) 2006 Arthur de Jong - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1301 USA -*/ - -#ifndef _LDAP_NSS_LDAP_LDAP_NSS_H -#define _LDAP_NSS_LDAP_LDAP_NSS_H - -/* for glibc, use weak aliases to pthreads functions */ -#ifdef HAVE_LIBC_LOCK_H -#include <libc-lock.h> -#elif defined(HAVE_BITS_LIBC_LOCK_H) -#include <bits/libc-lock.h> -#endif - -#include <time.h> -#include <sys/socket.h> -#include <netinet/in.h> -#ifdef HAVE_SHADOW_H -#include <shadow.h> -#endif - -#include <netdb.h> -#include <netinet/in.h> -#include <syslog.h> - -#include <nss.h> - -#include "ldap-schema.h" - -#ifndef NSS_BUFSIZ -#define NSS_BUFSIZ 1024 -#endif - -#ifndef NSS_BUFLEN_GROUP -#define NSS_BUFLEN_GROUP LDAP_NSS_BUFLEN_GROUP -#endif - -#ifndef LDAP_FILT_MAXSIZ -#define LDAP_FILT_MAXSIZ 1024 -#endif /* not LDAP_FILT_MAXSIZ */ - -#ifndef LDAPS_PORT -#define LDAPS_PORT 636 -#endif /* not LDAPS_PORT */ - -#ifdef DEBUG -#ifdef __XGNUC__ -#define debug(fmt, args...) fprintf(stderr, "nss_ldap: " fmt "\n" , ## args) -#else -#include <stdarg.h> -#include <stdio.h> -static void -debug (char *fmt, ...) -{ - va_list ap; - va_start (ap, fmt); - fprintf (stderr, "nss_ldap: "); - vfprintf (stderr, fmt, ap); - va_end (ap); - fprintf (stderr, "\n"); -} -#endif /* __GNUC__ */ -#else /* DEBUG */ -#ifdef __GNUC__ -#define debug(fmt, args...) -#else /* __GNUC__ */ -static void -debug (char *fmt, ...) -{ -} -#endif /* not __GNUC__ */ -#endif /* not DEBUG */ - -#ifdef __GNUC__ -#define alignof(ptr) __alignof__(ptr) -#elif defined(HAVE_ALIGNOF_H) -#include <alignof.h> -#else -#define alignof(ptr) (sizeof(char *)) -#endif /* __GNUC__ */ - -#define align(ptr, blen, TYPE)\ - { \ - char *qtr = ptr; \ - ptr += alignof(TYPE) - 1; \ - ptr -= ((ptr - (char *)NULL) % alignof(TYPE)); \ - blen -= (ptr - qtr); \ - } - -/* worst case */ -#define bytesleft(ptr, blen, TYPE) \ - ( (blen < alignof(TYPE)) ? 0 : (blen - alignof(TYPE) + 1)) - -/* selectors for different maps */ -enum ldap_map_selector -{ - LM_PASSWD, - LM_SHADOW, - LM_GROUP, - LM_HOSTS, - LM_SERVICES, - LM_NETWORKS, - LM_PROTOCOLS, - LM_RPC, - LM_ETHERS, - LM_NETMASKS, - LM_BOOTPARAMS, - LM_ALIASES, - LM_NETGROUP, - LM_NONE -}; - -enum ldap_userpassword_selector -{ - LU_RFC2307_USERPASSWORD, - LU_RFC3112_AUTHPASSWORD, - LU_OTHER_PASSWORD -}; - -enum ldap_shadow_selector -{ - LS_RFC2307_SHADOW, - LS_AD_SHADOW, - LS_OTHER_SHADOW -}; - -#ifndef UF_DONT_EXPIRE_PASSWD -#define UF_DONT_EXPIRE_PASSWD 0x10000 -#endif - -enum ldap_ssl_options -{ - SSL_OFF, - SSL_LDAPS, - SSL_START_TLS -}; - -enum ldap_reconnect_policy -{ - LP_RECONNECT_HARD_INIT, - LP_RECONNECT_HARD_OPEN, - LP_RECONNECT_SOFT -}; - -/* - * POSIX profile information (not used yet) - * see draft-joslin-config-schema-00.txt - */ -struct ldap_service_search_descriptor -{ - /* search base, qualified */ - char *lsd_base; - /* scope */ - int lsd_scope; - /* filter */ - char *lsd_filter; - /* next */ - struct ldap_service_search_descriptor *lsd_next; -}; - -/* maximum number of URIs */ -#define NSS_LDAP_CONFIG_URI_MAX 31 - -/* - * linked list of configurations pointing to LDAP servers. The first - * which has a successful ldap_open() is used. Conceivably the rest - * could be used after a failed or exhausted search. - */ -struct ldap_config -{ - /* NULL terminated list of URIs */ - char *ldc_uris[NSS_LDAP_CONFIG_URI_MAX + 1]; - /* default port, if not specified in URI */ - int ldc_port; - /* base DN, eg. dc=gnu,dc=org */ - char *ldc_base; - /* scope for searches */ - int ldc_scope; - /* dereference aliases/links */ - int ldc_deref; - /* bind DN */ - char *ldc_binddn; - /* bind cred */ - char *ldc_bindpw; - /* sasl auth id */ - char *ldc_saslid; - /* do we use sasl when binding? */ - int ldc_usesasl; - /* shadow bind DN */ - char *ldc_rootbinddn; - /* shadow bind cred */ - char *ldc_rootbindpw; - /* shadow sasl auth id */ - char *ldc_rootsaslid; - /* do we use sasl for root? */ - int ldc_rootusesasl; - /* protocol version */ - int ldc_version; - /* search timelimit */ - int ldc_timelimit; - /* bind timelimit */ - int ldc_bind_timelimit; - /* SSL enabled */ - enum ldap_ssl_options ldc_ssl_on; - /* SSL certificate path */ - char *ldc_sslpath; - /* Chase referrals */ - int ldc_referrals; - int ldc_restart; - /* naming contexts */ - struct ldap_service_search_descriptor *ldc_sds[LM_NONE]; - /* tls check peer */ - int ldc_tls_checkpeer; - /* tls ca certificate file */ - char *ldc_tls_cacertfile; - /* tls ca certificate dir */ - char *ldc_tls_cacertdir; - /* tls ciphersuite */ - char *ldc_tls_ciphers; - /* tls certificate */ - char *ldc_tls_cert; - /* tls key */ - char *ldc_tls_key; - /* tls randfile */ - char *ldc_tls_randfile; - /* idle timeout */ - time_t ldc_idle_timelimit; - /* reconnect policy */ - enum ldap_reconnect_policy ldc_reconnect_pol; - int ldc_reconnect_tries; - int ldc_reconnect_sleeptime; - int ldc_reconnect_maxsleeptime; - int ldc_reconnect_maxconntries; - /* sasl security */ - char *ldc_sasl_secprops; - /* DNS SRV RR domain */ - char *ldc_srv_domain; - /* directory for debug files */ - char *ldc_logdir; - /* LDAP debug level */ - int ldc_debug; - int ldc_pagesize; -#ifdef CONFIGURE_KRB5_CCNAME - /* krb5 ccache name */ - char *ldc_krb5_ccname; -#endif /* CONFIGURE_KRB5_CCNAME */ - /* attribute/objectclass maps relative to this config */ - void *ldc_maps[LM_NONE + 1][6]; /* must match MAP_MAX */ - /* is userPassword "userPassword" or not? ie. do we need {crypt} to be stripped */ - enum ldap_userpassword_selector ldc_password_type; - /* Use active directory time offsets? */ - enum ldap_shadow_selector ldc_shadow_type; - /* attribute table for ldap search requensts */ - const char **ldc_attrtab[LM_NONE + 1]; - unsigned int ldc_flags; - /* last modification time */ - time_t ldc_mtime; - char **ldc_initgroups_ignoreusers; -}; - -#if defined(__GLIBC__) && __GLIBC_MINOR__ > 1 -#else -#define ss_family sa_family -#endif /* __GLIBC__ */ - -enum ldap_session_state -{ - LS_UNINITIALIZED = -1, - LS_INITIALIZED, - LS_CONNECTED_TO_DSA -}; - -/* - * convenient wrapper around pointer into global config list, and a - * connection to an LDAP server. - */ -struct ldap_session -{ - /* the connection */ - LDAP *ls_conn; - /* pointer into config table */ - struct ldap_config *ls_config; - /* timestamp of last activity */ - time_t ls_timestamp; - /* has session been connected? */ - enum ldap_session_state ls_state; - /* keep track of the LDAP sockets */ - struct sockaddr_storage ls_sockname; - struct sockaddr_storage ls_peername; - /* index into ldc_uris: currently connected DSA */ - int ls_current_uri; -}; - -enum ldap_args_types -{ - LA_TYPE_STRING, - LA_TYPE_NUMBER, - LA_TYPE_STRING_AND_STRING, - LA_TYPE_NUMBER_AND_STRING, - LA_TYPE_TRIPLE, - LA_TYPE_STRING_LIST_OR, - LA_TYPE_STRING_LIST_AND, - LA_TYPE_NONE -}; - -enum ldap_map_type -{ - MAP_ATTRIBUTE = 0, - MAP_OBJECTCLASS, - MAP_OVERRIDE, - MAP_DEFAULT, - MAP_ATTRIBUTE_REVERSE, - MAP_OBJECTCLASS_REVERSE, /* XXX not used yet? */ - MAP_MAX = MAP_OBJECTCLASS_REVERSE -}; - -struct ldap_args -{ - enum ldap_args_types la_type; - union - { - const char *la_string; - long la_number; - struct { - /* for Solaris netgroup support */ - const char *host; - const char *user; - const char *domain; - } la_triple; - const char **la_string_list; - } - la_arg1; - union - { - const char *la_string; - } - la_arg2; - const char *la_base; /* override default base */ -}; - -#define LA_INIT(q) do { \ - (q).la_type = LA_TYPE_STRING; \ - (q).la_arg1.la_string = NULL; \ - (q).la_arg2.la_string = NULL; \ - (q).la_base = NULL; \ - } while (0) -#define LA_TYPE(q) ((q).la_type) -#define LA_STRING(q) ((q).la_arg1.la_string) -#define LA_NUMBER(q) ((q).la_arg1.la_number) -#define LA_TRIPLE(q) ((q).la_arg1.la_triple) -#define LA_STRING_LIST(q) ((q).la_arg1.la_string_list) -#define LA_STRING2(q) ((q).la_arg2.la_string) -#define LA_BASE(q) ((q).la_base) - -/* - * the state consists of the desired attribute value or an offset into a list of - * values for the desired attribute. This is necessary to support services. - * - * Be aware of the arbitary distinction between state and context. Context is - * the enumeration state of a lookup subsystem (which may be per-subsystem, - * or per-subsystem/per-thread, depending on the OS). State is the state - * of a particular lookup, and is only concerned with resolving and enumerating - * services. State is represented as instances of struct ldap_state; context as - * instances of struct ent_context. The latter contains the former. - */ -struct ldap_state -{ - int ls_type; - int ls_retry; -#define LS_TYPE_KEY (0) -#define LS_TYPE_INDEX (1) - union - { - /* ls_key is the requested attribute value. - ls_index is the desired offset into the value list. - */ - const char *ls_key; - int ls_index; - } - ls_info; -}; - -/* - * thread specific context: result chain, and state data - */ -struct ent_context -{ - struct ldap_state ec_state; /* eg. for services */ - int ec_msgid; /* message ID */ - LDAPMessage *ec_res; /* result chain */ - struct ldap_service_search_descriptor *ec_sd; /* current sd */ - struct berval *ec_cookie; /* cookie for paged searches */ -}; - -struct name_list -{ - char *name; - struct name_list *next; -}; - -typedef enum nss_status (*parser_t) (LDAPMessage *, struct ldap_state *, void *, - char *, size_t); - -typedef int (*NEWparser_t)(LDAPMessage *e,struct ldap_state *pvt,FILE *fp); - -/* - * Portable locking macro. - */ -#if defined(HAVE_THREAD_H) -#define NSS_LDAP_LOCK(m) mutex_lock(&m) -#define NSS_LDAP_UNLOCK(m) mutex_unlock(&m) -#define NSS_LDAP_DEFINE_LOCK(m) static mutex_t m = DEFAULTMUTEX -#elif defined(HAVE_LIBC_LOCK_H) || defined(HAVE_BITS_LIBC_LOCK_H) -#define NSS_LDAP_LOCK(m) __libc_lock_lock(m) -#define NSS_LDAP_UNLOCK(m) __libc_lock_unlock(m) -#define NSS_LDAP_DEFINE_LOCK(m) static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER -#elif defined(HAVE_PTHREAD_H) -#define NSS_LDAP_LOCK(m) pthread_mutex_lock(&m) -#define NSS_LDAP_UNLOCK(m) pthread_mutex_unlock(&m) -#define NSS_LDAP_DEFINE_LOCK(m) static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER -#else -#define NSS_LDAP_LOCK(m) -#define NSS_LDAP_UNLOCK(m) -#define NSS_LDAP_DEFINE_LOCK(m) -#endif - -/* - * Acquire global nss_ldap lock and blocks SIGPIPE. - * Generally this should only be done within ldap-nss.c. - */ -void _nss_ldap_enter (void); - -/* - * Release global nss_ldap lock and blocks SIGPIPE. - * Generally this should only be done within ldap-nss.c. - */ -void _nss_ldap_leave (void); - -/* - * _nss_ldap_ent_context_init() is called for each getXXent() call - * This will acquire the global mutex. - */ -struct ent_context *_nss_ldap_ent_context_init (struct ent_context **); - -/* - * _nss_ldap_ent_context_init_locked() has the same behaviour - * as above, except it assumes that the caller has acquired - * the lock - */ - -struct ent_context *_nss_ldap_ent_context_init_locked (struct ent_context **); - -/* - * _nss_ldap_ent_context_release() is used to manually free a context - */ -void _nss_ldap_ent_context_release (struct ent_context *); - -/* - * these are helper functions for ldap-grp.c only on Solaris - */ -char **_nss_ldap_get_values (LDAPMessage * e, const char *attr); -char *_nss_ldap_get_dn (LDAPMessage * e); -LDAPMessage *_nss_ldap_first_entry (LDAPMessage * res); -LDAPMessage *_nss_ldap_next_entry (LDAPMessage * res); -char *_nss_ldap_first_attribute (LDAPMessage * entry, BerElement **berptr); -char *_nss_ldap_next_attribute (LDAPMessage * entry, BerElement *ber); -const char **_nss_ldap_get_attributes (enum ldap_map_selector sel); - -/* - * Synchronous search cover (caller acquires lock). - */ -enum nss_status _nss_ldap_search_s (const struct ldap_args * args, /* IN */ - const char *filterprot, /* IN */ - enum ldap_map_selector sel, /* IN */ - const char **user_attrs, /* IN */ - int sizelimit, /* IN */ - LDAPMessage ** pRes /* OUT */ ); - -/* - * Emulate X.500 read operation. - */ -enum nss_status _nss_ldap_read (const char *dn, /* IN */ - const char **attributes, /* IN */ - LDAPMessage ** pRes /* OUT */ ); - -/* - * extended enumeration routine; uses asynchronous API. - * Caller must have acquired the global mutex - */ -enum nss_status _nss_ldap_getent_ex (struct ldap_args * args, /* IN */ - struct ent_context ** key, /* IN/OUT */ - void *result, /* IN/OUT */ - char *buffer, /* IN */ - size_t buflen, /* IN */ - int *errnop, /* OUT */ - const char *filterprot, /* IN */ - enum ldap_map_selector sel, /* IN */ - const char **user_attrs, /* IN */ - parser_t parser /* IN */ ); - -/* - * common enumeration routine; uses asynchronous API. - * Acquires the global mutex - */ -enum nss_status _nss_ldap_getent (struct ent_context ** key, /* IN/OUT */ - void *result, /* IN/OUT */ - char *buffer, /* IN */ - size_t buflen, /* IN */ - int *errnop, /* OUT */ - const char *filterprot, /* IN */ - enum ldap_map_selector sel, /* IN */ - parser_t parser /* IN */ ); - -/* - * common lookup routine; uses synchronous API. - */ -enum nss_status _nss_ldap_getbyname (struct ldap_args * args, /* IN/OUT */ - void *result, /* IN/OUT */ - char *buffer, /* IN */ - size_t buflen, /* IN */ - int *errnop, /* OUT */ - const char *filterprot, /* IN */ - enum ldap_map_selector sel, /* IN */ - parser_t parser /* IN */ ); - -int _nss_ldap_searchbyname(struct ldap_args *args, /* IN/OUT */ - const char *filterprot, /* IN */ - enum ldap_map_selector sel, /* IN */ - FILE *fp,NEWparser_t parser /* IN */ ); - - -/* parsing utility functions */ -enum nss_status _nss_ldap_assign_attrvals (LDAPMessage * e, /* IN */ - const char *attr, /* IN */ - const char *omitvalue, /* IN */ - char ***valptr, /* OUT */ - char **buffer, /* IN/OUT */ - size_t * buflen, /* IN/OUT */ - size_t * pvalcount /* OUT */ ); - -int _nss_ldap_write_attrvals(FILE *fp,LDAPMessage *e,const char *attr); - -enum nss_status _nss_ldap_assign_attrval (LDAPMessage * e, /* IN */ - const char *attr, /* IN */ - char **valptr, /* OUT */ - char **buffer, /* IN/OUT */ - size_t * buflen /* IN/OUT */ ); - - -const char *_nss_ldap_locate_userpassword (char **vals); - -enum nss_status _nss_ldap_assign_userpassword (LDAPMessage * e, /* IN */ - const char *attr, /* IN */ - char **valptr, /* OUT */ - char **buffer, /* IN/OUT */ - size_t * buflen); /* IN/OUT */ - -enum nss_status _nss_ldap_oc_check (LDAPMessage * e, const char *oc); - -int _nss_ldap_shadow_date(const char *val); -void _nss_ldap_shadow_handle_flag(struct spwd *sp); - -enum nss_status _nss_ldap_map_put (struct ldap_config * config, - enum ldap_map_selector sel, - enum ldap_map_type map, - const char *key, const char *value); - -enum nss_status _nss_ldap_map_get (struct ldap_config * config, - enum ldap_map_selector sel, - enum ldap_map_type map, - const char *key, const char **value); - -const char *_nss_ldap_map_at (enum ldap_map_selector sel, const char *pChar2); -const char *_nss_ldap_unmap_at (enum ldap_map_selector sel, const char *attribute); - -const char *_nss_ldap_map_oc (enum ldap_map_selector sel, const char *pChar); -const char *_nss_ldap_unmap_oc (enum ldap_map_selector sel, const char *pChar); - -const char *_nss_ldap_map_ov (const char *pChar); -const char *_nss_ldap_map_df (const char *pChar); - -enum nss_status _nss_ldap_proxy_bind (const char *user, const char *password); - -enum nss_status _nss_ldap_init (void); -void _nss_ldap_close (void); - -int _nss_ldap_test_config_flag (unsigned int flag); -int _nss_ldap_test_initgroups_ignoreuser (const char *user); - -#endif /* _LDAP_NSS_LDAP_LDAP_NSS_H */ diff --git a/server/ldap-schema.c b/server/ldap-schema.c deleted file mode 100644 index 4ae95a5..0000000 --- a/server/ldap-schema.c +++ /dev/null @@ -1,453 +0,0 @@ -/* - ldap-schema.c - LDAP schema information functions and definitions - This file was part of the nss_ldap library which has been - forked into the nss-ldapd library. - - Copyright (C) 1997-2005 Luke Howard - Copyright (C) 2006 West Consulting - Copyright (C) 2006 Arthur de Jong - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1301 USA -*/ - -#include "config.h" - -#include <stdlib.h> -#include <unistd.h> -#include <netdb.h> -#include <stdio.h> -#include <string.h> -#include <syslog.h> -#ifdef HAVE_LBER_H -#include <lber.h> -#endif -#ifdef HAVE_LDAP_H -#include <ldap.h> -#endif -#if defined(HAVE_THREAD_H) -#include <thread.h> -#elif defined(HAVE_PTHREAD_H) -#include <pthread.h> -#endif - -#include "ldap-nss.h" -#include "ldap-schema.h" -#include "util.h" - -/* max number of attributes per object class */ -#define ATTRTAB_SIZE 15 - -/** - * declare filters formerly declared in ldap-*.h - */ - -/* rfc822 mail aliases */ -char _nss_ldap_filt_getaliasbyname[LDAP_FILT_MAXSIZ]; -char _nss_ldap_filt_getaliasent[LDAP_FILT_MAXSIZ]; - -/* boot parameters */ -char _nss_ldap_filt_getbootparamsbyname[LDAP_FILT_MAXSIZ]; - -/* MAC address mappings */ -char _nss_ldap_filt_gethostton[LDAP_FILT_MAXSIZ]; -char _nss_ldap_filt_getntohost[LDAP_FILT_MAXSIZ]; -char _nss_ldap_filt_getetherent[LDAP_FILT_MAXSIZ]; - -/* groups */ -char _nss_ldap_filt_getgrnam[LDAP_FILT_MAXSIZ]; -char _nss_ldap_filt_getgrgid[LDAP_FILT_MAXSIZ]; -char _nss_ldap_filt_getgrent[LDAP_FILT_MAXSIZ]; -char _nss_ldap_filt_getgroupsbymemberanddn[LDAP_FILT_MAXSIZ]; -char _nss_ldap_filt_getgroupsbydn[LDAP_FILT_MAXSIZ]; -char _nss_ldap_filt_getpwnam_groupsbymember[LDAP_FILT_MAXSIZ]; -char _nss_ldap_filt_getgroupsbymember[LDAP_FILT_MAXSIZ]; - -/* IP hosts */ -char _nss_ldap_filt_gethostbyname[LDAP_FILT_MAXSIZ]; -char _nss_ldap_filt_gethostbyaddr[LDAP_FILT_MAXSIZ]; -char _nss_ldap_filt_gethostent[LDAP_FILT_MAXSIZ]; - -/* IP networks */ -char _nss_ldap_filt_getnetbyname[LDAP_FILT_MAXSIZ]; -char _nss_ldap_filt_getnetbyaddr[LDAP_FILT_MAXSIZ]; -char _nss_ldap_filt_getnetent[LDAP_FILT_MAXSIZ]; - -/* IP protocols */ -char _nss_ldap_filt_getprotobyname[LDAP_FILT_MAXSIZ]; -char _nss_ldap_filt_getprotobynumber[LDAP_FILT_MAXSIZ]; -char _nss_ldap_filt_getprotoent[LDAP_FILT_MAXSIZ]; - -/* users */ -char _nss_ldap_filt_getpwnam[LDAP_FILT_MAXSIZ]; -char _nss_ldap_filt_getpwuid[LDAP_FILT_MAXSIZ]; -char _nss_ldap_filt_getpwent[LDAP_FILT_MAXSIZ]; - -/* RPCs */ -char _nss_ldap_filt_getrpcbyname[LDAP_FILT_MAXSIZ]; -char _nss_ldap_filt_getrpcbynumber[LDAP_FILT_MAXSIZ]; -char _nss_ldap_filt_getrpcent[LDAP_FILT_MAXSIZ]; - -/* IP services */ -char _nss_ldap_filt_getservbyname[LDAP_FILT_MAXSIZ]; -char _nss_ldap_filt_getservbynameproto[LDAP_FILT_MAXSIZ]; -char _nss_ldap_filt_getservbyport[LDAP_FILT_MAXSIZ]; -char _nss_ldap_filt_getservbyportproto[LDAP_FILT_MAXSIZ]; -char _nss_ldap_filt_getservent[LDAP_FILT_MAXSIZ]; - -/* shadow users */ -char _nss_ldap_filt_getspnam[LDAP_FILT_MAXSIZ]; -char _nss_ldap_filt_getspent[LDAP_FILT_MAXSIZ]; - -/* netgroups */ -char _nss_ldap_filt_getnetgrent[LDAP_FILT_MAXSIZ]; -char _nss_ldap_filt_innetgr[LDAP_FILT_MAXSIZ]; - -/** - * lookup filter initialization - */ -void -_nss_ldap_init_filters () -{ - /* rfc822 mail aliases */ - snprintf (_nss_ldap_filt_getaliasbyname, LDAP_FILT_MAXSIZ, - "(&(%s=%s)(%s=%s))", AT (objectClass), OC (nisMailAlias), - ATM (LM_ALIASES, cn), "%s"); - snprintf (_nss_ldap_filt_getaliasent, LDAP_FILT_MAXSIZ, - "(%s=%s)", AT (objectClass), OC (nisMailAlias)); - - /* boot parameters */ - snprintf (_nss_ldap_filt_getbootparamsbyname, LDAP_FILT_MAXSIZ, - "(&(%s=%s)(%s=%s))", AT (objectClass), OC (bootableDevice), - ATM (LM_BOOTPARAMS, cn), "%d"); - - /* MAC address mappings */ - snprintf (_nss_ldap_filt_gethostton, LDAP_FILT_MAXSIZ, - "(&(%s=%s)(%s=%s))", AT (objectClass), OC (ieee802Device), - ATM (LM_ETHERS, cn), "%s"); - snprintf (_nss_ldap_filt_getntohost, LDAP_FILT_MAXSIZ, - "(&(%s=%s)(%s=%s))", AT (objectClass), OC (ieee802Device), AT (macAddress), - "%s"); - snprintf (_nss_ldap_filt_getetherent, LDAP_FILT_MAXSIZ, "(%s=%s)", - AT (objectClass), OC (ieee802Device)); - - /* groups */ - snprintf (_nss_ldap_filt_getgrnam, LDAP_FILT_MAXSIZ, - "(&(%s=%s)(%s=%s))", AT (objectClass), OC (posixGroup), - ATM (LM_GROUP, cn), "%s"); - snprintf (_nss_ldap_filt_getgrgid, LDAP_FILT_MAXSIZ, - "(&(%s=%s)(%s=%s))", AT (objectClass), OC (posixGroup), - ATM (LM_GROUP, gidNumber), "%d"); - snprintf (_nss_ldap_filt_getgrent, LDAP_FILT_MAXSIZ, "(&(%s=%s))", - AT (objectClass), OC (posixGroup)); - snprintf (_nss_ldap_filt_getgroupsbymemberanddn, LDAP_FILT_MAXSIZ, - "(&(%s=%s)(|(%s=%s)(%s=%s)))", - AT (objectClass), OC (posixGroup), AT (memberUid), "%s", AT (uniqueMember), "%s"); - snprintf (_nss_ldap_filt_getgroupsbydn, LDAP_FILT_MAXSIZ, - "(&(%s=%s)(%s=%s))", - AT (objectClass), OC (posixGroup), AT (uniqueMember), "%s"); - snprintf (_nss_ldap_filt_getpwnam_groupsbymember, LDAP_FILT_MAXSIZ, - "(|(&(%s=%s)(%s=%s))(&(%s=%s)(%s=%s)))", - AT (objectClass), OC (posixGroup), AT (memberUid), "%s", - AT (objectClass), OC (posixAccount), ATM (LM_PASSWD, uid), "%s"); - snprintf (_nss_ldap_filt_getgroupsbymember, LDAP_FILT_MAXSIZ, - "(&(%s=%s)(%s=%s))", AT (objectClass), OC (posixGroup), AT (memberUid), - "%s"); - - /* IP hosts */ - snprintf (_nss_ldap_filt_gethostbyname, LDAP_FILT_MAXSIZ, - "(&(%s=%s)(%s=%s))", AT (objectClass), OC (ipHost), ATM (LM_HOSTS, cn), - "%s"); - snprintf (_nss_ldap_filt_gethostbyaddr, LDAP_FILT_MAXSIZ, - "(&(%s=%s)(%s=%s))", AT (objectClass), OC (ipHost), AT (ipHostNumber), - "%s"); - snprintf (_nss_ldap_filt_gethostent, LDAP_FILT_MAXSIZ, "(%s=%s)", - AT (objectClass), OC (ipHost)); - - /* IP networks */ - snprintf (_nss_ldap_filt_getnetbyname, LDAP_FILT_MAXSIZ, - "(&(%s=%s)(%s=%s))", AT (objectClass), OC (ipNetwork), - ATM (LM_NETWORKS, cn), "%s"); - snprintf (_nss_ldap_filt_getnetbyaddr, LDAP_FILT_MAXSIZ, - "(&(%s=%s)(%s=%s))", AT (objectClass), OC (ipNetwork), - AT (ipNetworkNumber), "%s"); - snprintf (_nss_ldap_filt_getnetent, LDAP_FILT_MAXSIZ, "(%s=%s)", - AT (objectClass), OC (ipNetwork)); - - /* IP protocols */ - snprintf (_nss_ldap_filt_getprotobyname, LDAP_FILT_MAXSIZ, - "(&(%s=%s)(%s=%s))", AT (objectClass), OC (ipProtocol), - ATM (LM_PROTOCOLS, cn), "%s"); - snprintf (_nss_ldap_filt_getprotobynumber, LDAP_FILT_MAXSIZ, - "(&(%s=%s)(%s=%s))", AT (objectClass), OC (ipProtocol), - AT (ipProtocolNumber), "%d"); - snprintf (_nss_ldap_filt_getprotoent, LDAP_FILT_MAXSIZ, "(%s=%s)", - AT (objectClass), OC (ipProtocol)); - - /* users */ - snprintf (_nss_ldap_filt_getpwnam, LDAP_FILT_MAXSIZ, - "(&(%s=%s)(%s=%s))", AT (objectClass), OC (posixAccount), - ATM (LM_PASSWD, uid), "%s"); - snprintf (_nss_ldap_filt_getpwuid, LDAP_FILT_MAXSIZ, - "(&(%s=%s)(%s=%s))", - AT (objectClass), OC (posixAccount), AT (uidNumber), "%d"); - snprintf (_nss_ldap_filt_getpwent, LDAP_FILT_MAXSIZ, - "(%s=%s)", AT (objectClass), OC (posixAccount)); - - /* RPCs */ - snprintf (_nss_ldap_filt_getrpcbyname, LDAP_FILT_MAXSIZ, - "(&(%s=%s)(%s=%s))", AT (objectClass), OC (oncRpc), ATM (LM_RPC, cn), "%s"); - snprintf (_nss_ldap_filt_getrpcbynumber, LDAP_FILT_MAXSIZ, - "(&(%s=%s)(%s=%s))", AT (objectClass), OC (oncRpc), AT (oncRpcNumber), - "%d"); - snprintf (_nss_ldap_filt_getrpcent, LDAP_FILT_MAXSIZ, "(%s=%s)", - AT (objectClass), OC (oncRpc)); - - /* IP services */ - snprintf (_nss_ldap_filt_getservbyname, LDAP_FILT_MAXSIZ, - "(&(%s=%s)(%s=%s))", AT (objectClass), OC (ipService), ATM (LM_SERVICES, cn), - "%s"); - snprintf (_nss_ldap_filt_getservbynameproto, LDAP_FILT_MAXSIZ, - "(&(%s=%s)(%s=%s)(%s=%s))", - AT (objectClass), OC (ipService), ATM (LM_SERVICES, cn), "%s", AT (ipServiceProtocol), - "%s"); - snprintf (_nss_ldap_filt_getservbyport, LDAP_FILT_MAXSIZ, - "(&(%s=%s)(%s=%s))", AT (objectClass), OC (ipService), AT (ipServicePort), - "%d"); - snprintf (_nss_ldap_filt_getservbyportproto, LDAP_FILT_MAXSIZ, - "(&(%s=%s)(%s=%s)(%s=%s))", AT (objectClass), OC (ipService), - AT (ipServicePort), "%d", AT (ipServiceProtocol), "%s"); - snprintf (_nss_ldap_filt_getservent, LDAP_FILT_MAXSIZ, "(%s=%s)", - AT (objectClass), OC (ipService)); - - /* shadow users */ - snprintf (_nss_ldap_filt_getspnam, LDAP_FILT_MAXSIZ, - "(&(%s=%s)(%s=%s))", AT (objectClass), OC (shadowAccount), - ATM (LM_SHADOW, uid), "%s"); - snprintf (_nss_ldap_filt_getspent, LDAP_FILT_MAXSIZ, - "(%s=%s)", AT (objectClass), OC (shadowAccount)); - - /* netgroups */ - snprintf (_nss_ldap_filt_getnetgrent, LDAP_FILT_MAXSIZ, - "(&(%s=%s)(%s=%s))", AT (objectClass), OC (nisNetgroup), - ATM (LM_NETGROUP, cn), "%s"); - snprintf (_nss_ldap_filt_innetgr, LDAP_FILT_MAXSIZ, - "(&(%s=%s)(%s=%s))", AT (objectClass), OC (nisNetgroup), AT (memberNisNetgroup), "%s"); - -} - -static void init_pwd_attributes (const char ***pwd_attrs); -static void init_sp_attributes (const char ***sp_attrs); -static void init_grp_attributes (const char ***grp_attrs); -static void init_hosts_attributes (const char ***hosts_attrs); -static void init_services_attributes (const char ***services_attrs); -static void init_network_attributes (const char ***network_attrs); -static void init_proto_attributes (const char ***proto_attrs); -static void init_rpc_attributes (const char ***rpc_attrs); -static void init_ethers_attributes (const char ***ethers_attrs); -static void init_bp_attributes (const char ***bp_attrs); -static void init_alias_attributes (const char ***alias_attrs); -static void init_netgrp_attributes (const char ***netgrp_attrs); - -/** - * attribute table initialization routines - */ -void -_nss_ldap_init_attributes (const char ***attrtab) -{ - init_pwd_attributes (&attrtab[LM_PASSWD]); - init_sp_attributes (&attrtab[LM_SHADOW]); - init_grp_attributes (&attrtab[LM_GROUP]); - init_hosts_attributes (&attrtab[LM_HOSTS]); - init_services_attributes (&attrtab[LM_SERVICES]); - init_network_attributes (&attrtab[LM_NETWORKS]); - init_proto_attributes (&attrtab[LM_PROTOCOLS]); - init_rpc_attributes (&attrtab[LM_RPC]); - init_ethers_attributes (&attrtab[LM_ETHERS]); - init_network_attributes (&attrtab[LM_NETMASKS]); - init_bp_attributes (&attrtab[LM_BOOTPARAMS]); - init_alias_attributes (&attrtab[LM_ALIASES]); - init_netgrp_attributes (&attrtab[LM_NETGROUP]); - - attrtab[LM_NONE] = NULL; -} - -static void -init_pwd_attributes (const char ***pwd_attrs) -{ - int i = 0; - static const char *__pwd_attrs[ATTRTAB_SIZE + 1]; - - (*pwd_attrs) = __pwd_attrs; - - (*pwd_attrs)[i++] = ATM (LM_PASSWD, uid); - (*pwd_attrs)[i++] = ATM (LM_PASSWD, userPassword); - (*pwd_attrs)[i++] = AT (uidNumber); - (*pwd_attrs)[i++] = ATM (LM_PASSWD, gidNumber); - (*pwd_attrs)[i++] = ATM (LM_PASSWD, cn); - (*pwd_attrs)[i++] = AT (homeDirectory); - (*pwd_attrs)[i++] = AT (loginShell); - (*pwd_attrs)[i++] = AT (gecos); - (*pwd_attrs)[i++] = ATM (LM_PASSWD, description); - (*pwd_attrs)[i++] = AT (objectClass); - (*pwd_attrs)[i] = NULL; -} - -static void -init_sp_attributes (const char ***sp_attrs) -{ - static const char *__sp_attrs[ATTRTAB_SIZE + 1]; - - (*sp_attrs) = __sp_attrs; - - (*sp_attrs)[0] = (char *) ATM (LM_SHADOW, uid); - (*sp_attrs)[1] = (char *) ATM (LM_SHADOW, userPassword); - (*sp_attrs)[2] = (char *) AT (shadowLastChange); - (*sp_attrs)[3] = (char *) AT (shadowMax); - (*sp_attrs)[4] = (char *) AT (shadowMin); - (*sp_attrs)[5] = (char *) AT (shadowWarning); - (*sp_attrs)[6] = (char *) AT (shadowInactive); - (*sp_attrs)[7] = (char *) AT (shadowExpire); - (*sp_attrs)[8] = (char *) AT (shadowFlag); - (*sp_attrs)[9] = NULL; -} - -static void -init_grp_attributes (const char ***grp_attrs) -{ - int i = 0; - static const char *__grp_attrs[ATTRTAB_SIZE + 1]; - - (*grp_attrs) = __grp_attrs; - - (*grp_attrs)[i++] = (char *) ATM (LM_GROUP, cn); - (*grp_attrs)[i++] = (char *) ATM (LM_GROUP, userPassword); - (*grp_attrs)[i++] = (char *) AT (memberUid); - if (_nss_ldap_test_config_flag (NSS_LDAP_FLAGS_RFC2307BIS)) - (*grp_attrs)[i++] = (char *) AT (uniqueMember); - (*grp_attrs)[i++] = (char *) ATM (LM_GROUP, gidNumber); - (*grp_attrs)[i] = NULL; -} - -static void -init_hosts_attributes (const char ***hosts_attrs) -{ - static const char *__hosts_attrs[ATTRTAB_SIZE + 1]; - - (*hosts_attrs) = __hosts_attrs; - - (*hosts_attrs)[0] = (char *) ATM (LM_HOSTS, cn); - (*hosts_attrs)[1] = (char *) AT (ipHostNumber); - (*hosts_attrs)[2] = NULL; -} - -static void -init_services_attributes (const char ***services_attrs) -{ - static const char *__services_attrs[ATTRTAB_SIZE + 1]; - - (*services_attrs) = __services_attrs; - - (*services_attrs)[0] = ATM (LM_SERVICES, cn); - (*services_attrs)[1] = AT (ipServicePort); - (*services_attrs)[2] = AT (ipServiceProtocol); - (*services_attrs)[3] = NULL; -} - -static void -init_network_attributes (const char ***network_attrs) -{ - static const char *__network_attrs[ATTRTAB_SIZE + 1]; - - (*network_attrs) = __network_attrs; - - (*network_attrs)[0] = ATM (LM_NETWORKS, cn); - (*network_attrs)[1] = AT (ipNetworkNumber); - (*network_attrs)[2] = AT (ipNetmaskNumber); - (*network_attrs)[3] = NULL; -} - -static void -init_proto_attributes (const char ***proto_attrs) -{ - static const char *__proto_attrs[ATTRTAB_SIZE + 1]; - - (*proto_attrs) = __proto_attrs; - - (*proto_attrs)[0] = ATM (LM_PROTOCOLS, cn); - (*proto_attrs)[1] = AT (ipProtocolNumber); - (*proto_attrs)[2] = NULL; -} - -static void -init_rpc_attributes (const char ***rpc_attrs) -{ - static const char *__rpc_attrs[ATTRTAB_SIZE + 1]; - - (*rpc_attrs) = __rpc_attrs; - - (*rpc_attrs)[0] = ATM (LM_RPC, cn); - (*rpc_attrs)[1] = AT (oncRpcNumber); - (*rpc_attrs)[2] = NULL; -} - -static void -init_ethers_attributes (const char ***ethers_attrs) -{ - static const char *__ethers_attrs[ATTRTAB_SIZE + 1]; - - (*ethers_attrs) = __ethers_attrs; - - (*ethers_attrs)[0] = ATM (LM_ETHERS, cn); - (*ethers_attrs)[1] = AT (macAddress); - (*ethers_attrs)[2] = NULL; -} - -static void -init_bp_attributes (const char ***bp_attrs) -{ - static const char *__bp_attrs[ATTRTAB_SIZE + 1]; - - (*bp_attrs) = __bp_attrs; - - (*bp_attrs)[0] = ATM (LM_BOOTPARAMS, cn); - (*bp_attrs)[1] = AT (bootParameter); - (*bp_attrs)[2] = NULL; -} - -static void -init_alias_attributes (const char ***alias_attrs) -{ - static const char *__alias_attrs[ATTRTAB_SIZE + 1]; - - (*alias_attrs) = __alias_attrs; - - (*alias_attrs)[0] = ATM (LM_ALIASES, cn); - (*alias_attrs)[1] = AT (rfc822MailMember); - (*alias_attrs)[2] = NULL; -} - -static void -init_netgrp_attributes (const char ***netgrp_attrs) -{ - static const char *__netgrp_attrs[ATTRTAB_SIZE + 1]; - - (*netgrp_attrs) = __netgrp_attrs; - - (*netgrp_attrs)[0] = ATM (LM_NETGROUP, cn); - (*netgrp_attrs)[1] = AT (nisNetgroupTriple); - (*netgrp_attrs)[2] = AT (memberNisNetgroup); - (*netgrp_attrs)[3] = NULL; -} diff --git a/server/ldap-schema.h b/server/ldap-schema.h deleted file mode 100644 index 558c1aa..0000000 --- a/server/ldap-schema.h +++ /dev/null @@ -1,303 +0,0 @@ -/* - ldap-schema.h - LDAP schema information functions and definitions - This file was part of the nss_ldap library which has been - forked into the nss-ldapd library. - - Copyright (C) 1997-2005 Luke Howard - Copyright (C) 2006 West Consulting - Copyright (C) 2006 Arthur de Jong - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1301 USA -*/ - -#ifndef _LDAP_NSS_LDAP_LDAP_SCHEMA_H -#define _LDAP_NSS_LDAP_LDAP_SCHEMA_H - -/** - * function to initialize global lookup filters. - */ -void _nss_ldap_init_filters(void); -void _nss_ldap_init_attributes(const char ***attrtab); - -/** - * make filters formerly declared in ldap-*.h globally available. - */ - -/* rfc822 mail aliases */ -extern char _nss_ldap_filt_getaliasbyname[]; -extern char _nss_ldap_filt_getaliasent[]; - -/* boot parameters */ -extern char _nss_ldap_filt_getbootparamsbyname[]; - -/* MAC address mappings */ -extern char _nss_ldap_filt_gethostton[]; -extern char _nss_ldap_filt_getntohost[]; -extern char _nss_ldap_filt_getetherent[]; - -/* groups */ -extern char _nss_ldap_filt_getgrnam[]; -extern char _nss_ldap_filt_getgrgid[]; -extern char _nss_ldap_filt_getgrent[]; -extern char _nss_ldap_filt_getgroupsbymemberanddn[]; -extern char _nss_ldap_filt_getgroupsbydn[]; -extern char _nss_ldap_filt_getpwnam_groupsbymember[]; -extern char _nss_ldap_filt_getgroupsbymember[]; - -/* IP hosts */ -extern char _nss_ldap_filt_gethostbyname[]; -extern char _nss_ldap_filt_gethostbyaddr[]; -extern char _nss_ldap_filt_gethostent[]; - -/* IP networks */ -extern char _nss_ldap_filt_getnetbyname[]; -extern char _nss_ldap_filt_getnetbyaddr[]; -extern char _nss_ldap_filt_getnetent[]; - -/* IP protocols */ -extern char _nss_ldap_filt_getprotobyname[]; -extern char _nss_ldap_filt_getprotobynumber[]; -extern char _nss_ldap_filt_getprotoent[]; - -/* users */ -extern char _nss_ldap_filt_getpwnam[]; -extern char _nss_ldap_filt_getpwuid[]; -extern char _nss_ldap_filt_getpwent[]; - -/* RPCs */ -extern char _nss_ldap_filt_getrpcbyname[]; -extern char _nss_ldap_filt_getrpcbynumber[]; -extern char _nss_ldap_filt_getrpcent[]; - -/* IP services */ -extern char _nss_ldap_filt_getservbyname[]; -extern char _nss_ldap_filt_getservbynameproto[]; -extern char _nss_ldap_filt_getservbyport[]; -extern char _nss_ldap_filt_getservbyportproto[]; -extern char _nss_ldap_filt_getservent[]; - -/* shadow users */ -extern char _nss_ldap_filt_getspnam[]; -extern char _nss_ldap_filt_getspent[]; - -/* netgroups */ -extern char _nss_ldap_filt_getnetgrent[]; -extern char _nss_ldap_filt_innetgr[]; - -/** - * Initialize attribute vector table indexed by map - * selector (eg. LM_PASSWD) relative to an "ldap_config" - */ - -/** - * Lookup (potentially mapped) - * objectclass/attribute. - */ -#define OC(oc) _nss_ldap_map_oc(LM_NONE, OC##_##oc) -#define OCM(map, at) _nss_ldap_map_oc(map, AT##_##at) -#define AT(at) _nss_ldap_map_at(LM_NONE, AT##_##at) -#define ATM(map, at) _nss_ldap_map_at(map, AT##_##at) -#define DF(at) _nss_ldap_map_df(at) -#define OV(at) _nss_ldap_map_ov(at) - -/** - * Common attributes, not from RFC 2307. - */ -#define AT_objectClass "objectClass" -#define AT_cn "cn" -#define AT_description "description" -#define AT_l "l" -#define AT_manager "manager" - -/** - * Vendor-specific attributes and object classes. - * (Mainly from Sun.) - */ -#define OC_nisMailAlias "nisMailAlias" -#define AT_rfc822MailMember "rfc822MailMember" - -/** - * RFC 2307 attributes and object classes. - */ - -/* - * ( 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 ) ) - */ -#define OC_posixAccount "posixAccount" -#define AT_uid "uid" -#define AT_userPassword "userPassword" -#define AT_uidNumber "uidNumber" -#define AT_gidNumber "gidNumber" -#define AT_loginShell "loginShell" -#define AT_gecos "gecos" -#define AT_homeDirectory "homeDirectory" - -/* - * ( 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 ) ) - */ -#define OC_shadowAccount "shadowAccount" -#define AT_shadowLastChange "shadowLastChange" -#define AT_shadowMin "shadowMin" -#define AT_shadowMax "shadowMax" -#define AT_shadowWarning "shadowWarning" -#define AT_shadowInactive "shadowInactive" -#define AT_shadowExpire "shadowExpire" -#define AT_shadowFlag "shadowFlag" - -/* - * ( nisSchema.2.2 NAME 'posixGroup' SUP top STRUCTURAL - * DESC 'Abstraction of a group of accounts' - * MUST ( cn $ gidNumber ) - * MAY ( userPassword $ uidMember $ description ) ) - */ -#define OC_posixGroup "posixGroup" -#define AT_gidNumber "gidNumber" -#define AT_memberUid "memberUid" -#define AT_uniqueMember "uniqueMember" -#define AT_memberOf "memberOf" - -/* - * ( 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 ) ) - */ -#define OC_ipService "ipService" -#define AT_ipServicePort "ipServicePort" -#define AT_ipServiceProtocol "ipServiceProtocol" - -/* - * ( 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 ) - */ -#define OC_ipProtocol "ipProtocol" -#define AT_ipProtocolNumber "ipProtocolNumber" - -/* - * ( 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 ) - */ -#define OC_oncRpc "oncRpc" -#define AT_oncRpcNumber "oncRpcNumber" - -/* - * ( 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 ) ) - */ -#define OC_ipHost "ipHost" -#define AT_ipHostNumber "ipHostNumber" - -/* - * ( 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 ) ) - */ -#define OC_ipNetwork "ipNetwork" -#define AT_ipNetworkNumber "ipNetworkNumber" -#define AT_ipNetmaskNumber "ipNetmaskNumber" - -/* - * ( nisSchema.2.8 NAME 'nisNetgroup' SUP top STRUCTURAL - * DESC 'Abstraction of a netgroup. May refer to other netgroups' - * MUST cn - * MAY ( nisNetgroupTriple $ memberNisNetgroup $ description ) ) - */ -#define OC_nisNetgroup "nisNetgroup" -#define AT_nisNetgroupTriple "nisNetgroupTriple" -#define AT_memberNisNetgroup "memberNisNetgroup" - -/* - * ( nisSchema.2.09 NAME 'nisMap' SUP top STRUCTURAL - * DESC 'A generic abstraction of a NIS map' - * MUST nisMapName - * MAY description ) - */ -#define OC_nisMap "nisMap" -#define AT_nisMapName "nisNapName" - -/* - * ( nisSchema.2.10 NAME 'nisObject' SUP top STRUCTURAL - * DESC 'An entry in a NIS map' - * MUST ( cn $ nisMapEntry $ nisMapName ) - * MAY description ) - */ -#define OC_nisObject "nisObject" -#define AT_nisMapEntry "nisMapEntry" - -/* - * ( 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 ) - */ -#define OC_ieee802Device "ieee802Device" -#define AT_macAddress "macAddress" - -/* - * ( nisSchema.2.12 NAME 'bootableDevice' SUP top AUXILIARY - * DESC 'A device with boot parameters; device SHOULD be - * used as a structural class' - * MAY ( bootFile $ bootParameter ) ) - */ -#define OC_bootableDevice "bootableDevice" -#define AT_bootFile "bootFile" -#define AT_bootParameter "bootParameter" - -/* - * Map names - */ -#define MP_passwd "passwd" -#define MP_shadow "shadow" -#define MP_group "group" -#define MP_hosts "hosts" -#define MP_services "services" -#define MP_networks "networks" -#define MP_protocols "protocols" -#define MP_rpc "rpc" -#define MP_ethers "ethers" -#define MP_netmasks "netmasks" -#define MP_bootparams "bootparams" -#define MP_aliases "aliases" -#define MP_netgroup "netgroup" - -#endif /* _LDAP_NSS_LDAP_LDAP_SCHEMA_H */ diff --git a/server/log.c b/server/log.c deleted file mode 100644 index c7370cf..0000000 --- a/server/log.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - log.c - logging funtions - - Copyright (C) 2002, 2003 Arthur de Jong - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1301 USA -*/ - - -#include "config.h" - -#include <stdio.h> -#include <sys/types.h> -#include <unistd.h> -#include <syslog.h> -#include <stdarg.h> -#include <errno.h> -#include <string.h> - -#include "log.h" -#include "xmalloc.h" - - -/* set the logname */ -#undef PACKAGE -#define PACKAGE "nslcd" - - -/* storage for logging modes */ -static struct cvsd_log { - FILE *fp; /* NULL==syslog */ - int loglevel; - struct cvsd_log *next; -} *cvsd_loglist=NULL; - - -/* default loglevel when no logging is configured */ -static int prelogging_loglevel=LOG_INFO; - - -/* set loglevel when no logging is configured */ -void log_setdefaultloglevel(int loglevel) -{ - prelogging_loglevel=loglevel; -} - - -/* add logging method to configuration list */ -static void log_addlogging_fp(FILE *fp,int loglevel) -{ - struct cvsd_log *tmp,*lst; - /* create new logstruct */ - tmp=(struct cvsd_log *)xmalloc(sizeof(struct cvsd_log)); - tmp->fp=fp; - tmp->loglevel=loglevel; - tmp->next=NULL; - /* save the struct in the list */ - if (cvsd_loglist==NULL) - cvsd_loglist=tmp; - else - { - for (lst=cvsd_loglist;lst->next!=NULL;lst=lst->next); - lst->next=tmp; - } -} - - -/* configure logging to a file */ -void log_addlogging_file(const char *filename,int loglevel) -{ - FILE *fp; - fp=fopen(filename,"a"); - if (fp==NULL) - { - log_log(LOG_ERR,"cannot open logfile (%s) for appending: %s",filename,strerror(errno)); - exit(1); - } - log_addlogging_fp(fp,loglevel); -} - - -/* configure logging to syslog */ -void log_addlogging_syslog(int loglevel) -{ - openlog(PACKAGE,LOG_PID,LOG_DAEMON); - log_addlogging_fp(NULL,loglevel); -} - - -/* configure a null logging mode (no logging) */ -void log_addlogging_none() -{ - /* this is a hack, but it's so easy */ - log_addlogging_fp(NULL,LOG_EMERG); -} - - -/* start the logging with the configured logging methods - if no method is configured yet, logging is done to syslog */ -void log_startlogging(void) -{ - if (cvsd_loglist==NULL) - log_addlogging_syslog(LOG_INFO); - prelogging_loglevel=-1; -} - - -/* log the given message using the configured logging method */ -void log_log(int pri,const char *format, ...) -{ - int res; - struct cvsd_log *lst; - /* TODO: make this something better */ - #define maxbufferlen 120 - char buffer[maxbufferlen]; - va_list ap; - /* make the message */ - va_start(ap,format); - res=vsnprintf(buffer,maxbufferlen,format,ap); - if ((res<0)||(res>=maxbufferlen)) - { - /* truncate with "..." */ - buffer[maxbufferlen-2]='.'; - buffer[maxbufferlen-3]='.'; - buffer[maxbufferlen-4]='.'; - } - buffer[maxbufferlen-1]='\0'; - va_end(ap); - /* do the logging */ - if (prelogging_loglevel>=0) - { - /* if logging is not yet defined, log to stderr */ - if (pri<=prelogging_loglevel) - fprintf(stderr,"%s: %s%s\n",PACKAGE,pri==LOG_DEBUG?"DEBUG: ":"",buffer); - } - else - { - for (lst=cvsd_loglist;lst!=NULL;lst=lst->next) - { - if (pri<=lst->loglevel) - { - if (lst->fp==NULL) /* syslog */ - syslog(pri,"%s",buffer); - else /* file */ - { - fprintf(lst->fp,"%s: %s\n",PACKAGE,buffer); - fflush(lst->fp); - } - } - } - } -} - - -/* return the syslog loglevel represented by the string - return -1 on unknown */ -int log_getloglevel(const char *lvl) -{ - if ( strcmp(lvl,"crit")==0 ) - return LOG_CRIT; - else if ( (strcmp(lvl,"error")==0) || - (strcmp(lvl,"err")==0) ) - return LOG_ERR; - else if ( strcmp(lvl,"warning")==0 ) - return LOG_WARNING; - else if ( strcmp(lvl,"notice")==0 ) - return LOG_NOTICE; - else if ( strcmp(lvl,"info")==0 ) - return LOG_INFO; - else if ( strcmp(lvl,"debug")==0 ) - return LOG_DEBUG; - else - return -1; /* unknown */ -} diff --git a/server/log.h b/server/log.h deleted file mode 100644 index 4124fbe..0000000 --- a/server/log.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - log.h - definitions of logging funtions - - Copyright (C) 2002, 2003 Arthur de Jong - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1301 USA -*/ - - -#ifndef _LOG_H -#define _LOG_H 1 - - -#include <syslog.h> - - -/* set loglevel when no logging is configured */ -void log_setdefaultloglevel(int loglevel); - - -/* configure logging to a file */ -void log_addlogging_file(const char *filename,int loglevel); - - -/* configure logging to syslog */ -void log_addlogging_syslog(int loglevel); - - -/* configure a null logging mode (no logging) */ -void log_addlogging_none(void); - - -/* start the logging with the configured logging methods - if no method is configured yet, logging is done to syslog */ -void log_startlogging(void); - - -/* log the given message using the configured logging method */ -void log_log(int pri,const char *format, ...); - - -/* return the syslog loglevel represented by the string - return -1 on unknown */ -int log_getloglevel(const char *lvl); - - -#endif /* not _LOG_H */ diff --git a/server/netgroup.c b/server/netgroup.c deleted file mode 100644 index e79657d..0000000 --- a/server/netgroup.c +++ /dev/null @@ -1,354 +0,0 @@ -/* - netgroup.c - netgroup lookup routines - This file was part of the nss_ldap library (as ldap-netgrp.c) - which has been forked into the nss-ldapd library. - This file also contains code that is taken from the GNU C - Library (nss/nss_files/files-netgrp.c). - - Copyright (C) 1996, 1997, 2000 Free Software Foundation, Inc. - Copyright (C) 1997-2005 Luke Howard - Copyright (C) 2006 West Consulting - Copyright (C) 2006 Arthur de Jong - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1301 USA -*/ - -#include "config.h" - -#include <stdio.h> -#include <stdarg.h> -#include <ctype.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/param.h> -#include <string.h> -#include <assert.h> -#if defined(HAVE_THREAD_H) -#include <thread.h> -#elif defined(HAVE_PTHREAD_H) -#include <pthread.h> -#endif -#ifdef HAVE_LBER_H -#include <lber.h> -#endif -#ifdef HAVE_LDAP_H -#include <ldap.h> -#endif - -#include "ldap-nss.h" -#include "util.h" -#include "common.h" -#include "log.h" - -/* A netgroup can consist of names of other netgroups. We have to - track which netgroups were read and which still have to be read. */ - -/* Dataset for iterating netgroups. */ -struct __netgrent -{ - enum - { triple_val, group_val } - type; - - union - { - struct - { - const char *host; - const char *user; - const char *domain; - } - triple; - - const char *group; - } - val; - - /* Room for the data kept between the calls to the netgroup - functions. We must avoid global variables. */ - char *data; - size_t data_size; - char *cursor; - int first; - - struct name_list *known_groups; - struct name_list *needed_groups; -}; - -/* - * I (Luke Howard) pulled the following macro (EXPAND), functions - * (strip_whitespace and _nss_netgroup_parseline) and structures - * (name_list and __netgrent) from glibc-2.2.x. _nss_netgroup_parseline - * became _nss_ldap_parse_netgr after some modification. - * - * The rest of the code is modeled on various other _nss_ldap functions. - */ - -#define EXPAND(needed) \ - do \ - { \ - size_t old_cursor = result->cursor - result->data; \ - \ - result->data_size += 512 > 2 * needed ? 512 : 2 * needed; \ - result->data = realloc (result->data, result->data_size); \ - \ - if (result->data == NULL) \ - { \ - stat = NSS_STATUS_UNAVAIL; \ - goto out; \ - } \ - \ - result->cursor = result->data + old_cursor; \ - } \ - while (0) - -static char * -strip_whitespace (char *str) -{ - char *cp = str; - - /* Skip leading spaces. */ - while (isspace ((int) *cp)) - cp++; - - str = cp; - while (*cp != '\0' && !isspace ((int) *cp)) - cp++; - - /* Null-terminate, stripping off any trailing spaces. */ - *cp = '\0'; - - return *str == '\0' ? NULL : str; -} - -static enum nss_status -_nss_ldap_parse_netgr (void *vresultp, char *buffer, size_t buflen) -{ - struct __netgrent *result = (struct __netgrent *) vresultp; - char *cp = result->cursor; - char *user, *host, *domain; - - /* The netgroup either doesn't exist or is empty. */ - if (cp == NULL) - return NSS_STATUS_RETURN; - - /* First skip leading spaces. */ - while (isspace ((int) *cp)) - ++cp; - - if (*cp != '(') - { - /* We have a list of other netgroups. */ - char *name = cp; - - while (*cp != '\0' && !isspace ((int) *cp)) - ++cp; - - if (name != cp) - { - /* It is another netgroup name. */ - int last = *cp == '\0'; - - result->type = group_val; - result->val.group = name; - *cp = '\0'; - if (!last) - ++cp; - result->cursor = cp; - result->first = 0; - - return NSS_STATUS_SUCCESS; - } - return result->first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN; - } - - /* Match host name. */ - host = ++cp; - while (*cp != ',') - if (*cp++ == '\0') - return result->first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN; - - /* Match user name. */ - user = ++cp; - while (*cp != ',') - if (*cp++ == '\0') - return result->first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN; - - /* Match domain name. */ - domain = ++cp; - while (*cp != ')') - if (*cp++ == '\0') - return result->first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN; - ++cp; - - /* When we got here we have found an entry. Before we can copy it - to the private buffer we have to make sure it is big enough. */ - if (cp - host > buflen) - return NSS_STATUS_TRYAGAIN; - - strncpy (buffer, host, cp - host); - result->type = triple_val; - - buffer[(user - host) - 1] = '\0'; - result->val.triple.host = strip_whitespace (buffer); - - buffer[(domain - host) - 1] = '\0'; - result->val.triple.user = strip_whitespace (buffer + (user - host)); - - buffer[(cp - host) - 1] = '\0'; - result->val.triple.domain = strip_whitespace (buffer + (domain - host)); - - /* Remember where we stopped reading. */ - result->cursor = cp; - result->first = 0; - - return NSS_STATUS_SUCCESS; -} - -static enum nss_status -_nss_ldap_load_netgr (LDAPMessage * e, - struct ldap_state * pvt, - void *vresultp, char *buffer, size_t buflen) -{ - int attr; - int nvals; - int valcount = 0; - char **vals; - char **valiter; - struct __netgrent *result = vresultp; - enum nss_status stat = NSS_STATUS_SUCCESS; - - for (attr = 0; attr < 2; attr++) - { - switch (attr) - { - case 1: - vals = _nss_ldap_get_values (e, AT (nisNetgroupTriple)); - break; - default: - vals = _nss_ldap_get_values (e, AT (memberNisNetgroup)); - break; - } - - nvals = ldap_count_values (vals); - - if (vals == NULL) - continue; - - if (nvals == 0) - { - ldap_value_free (vals); - continue; - } - - if (result->data_size > 0 - && result->cursor - result->data + 1 > result->data_size) - EXPAND (1); - - if (result->data_size > 0) - *result->cursor++ = ' '; - - valcount += nvals; - valiter = vals; - - while (*valiter != NULL) - { - int curlen = strlen (*valiter); - if (result->cursor - result->data + curlen + 1 > result->data_size) - EXPAND (curlen + 1); - memcpy (result->cursor, *valiter, curlen + 1); - result->cursor += curlen; - valiter++; - if (*valiter != NULL) - *result->cursor++ = ' '; - } - ldap_value_free (vals); - } - - result->first = 1; - result->cursor = result->data; - -out: - - return stat; -} - -int nslcd_netgroup_byname(FILE *fp) -{ - - int32_t tmpint32; - static struct ent_context *netgroup_context=NULL; - char *name; - /* these are here for now until we rewrite the LDAP code */ - struct __netgrent result; - char buffer[1024]; - int errnop; - struct ldap_args a; - enum nss_status stat=NSS_STATUS_SUCCESS; - /* read request parameters */ - READ_STRING_ALLOC(fp,name); - /* log call */ - log_log(LOG_DEBUG,"nslcd_netgroup_byname(%s)",name); - /* write the response header */ - WRITE_INT32(fp,NSLCD_VERSION); - WRITE_INT32(fp,NSLCD_ACTION_NETGROUP_BYNAME); - /* initialize structure */ - result.data=result.cursor=NULL; - result.data_size = 0; - /* do initial ldap request */ - LA_INIT(a); - LA_STRING(a)=name; - LA_TYPE(a)=LA_TYPE_STRING; - stat=_nss_ldap_getbyname(&a,&result,buffer,1024,&errnop,_nss_ldap_filt_getnetgrent,LM_NETGROUP,_nss_ldap_load_netgr); - if (_nss_ldap_ent_context_init(&netgroup_context)==NULL) - return -1; - /* loop over all results */ - while ((stat=_nss_ldap_parse_netgr(&result,buffer,1024))==NSS_STATUS_SUCCESS) - { - if (result.type==triple_val) - { - WRITE_INT32(fp,NSLCD_RESULT_SUCCESS); - WRITE_INT32(fp,NETGROUP_TYPE_TRIPLE); - if (result.val.triple.host==NULL) - { WRITE_STRING(fp,""); } - else - { WRITE_STRING(fp,result.val.triple.host); } - if (result.val.triple.user==NULL) - { WRITE_STRING(fp,""); } - else - { WRITE_STRING(fp,result.val.triple.user); } - if (result.val.triple.domain==NULL) - { WRITE_STRING(fp,""); } - else - { WRITE_STRING(fp,result.val.triple.domain); } - } - else if (result.type==group_val) - { - WRITE_INT32(fp,NSLCD_RESULT_SUCCESS); - WRITE_INT32(fp,NETGROUP_TYPE_NETGROUP); - WRITE_STRING(fp,result.val.group); - } - } - /* free data */ - if (result.data!=NULL) - free(result.data); - /* we're done */ - _nss_ldap_enter(); - _nss_ldap_ent_context_release(netgroup_context); - _nss_ldap_leave(); - return 0; -} - diff --git a/server/network.c b/server/network.c deleted file mode 100644 index e44a3e1..0000000 --- a/server/network.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - network.c - network address entry lookup routines - This file was part of the nss_ldap library (as ldap-network.c) - which has been forked into the nss-ldapd library. - - Copyright (C) 1997-2005 Luke Howard - Copyright (C) 2006 West Consulting - Copyright (C) 2006 Arthur de Jong - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1301 USA -*/ - -#include "config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <netdb.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <arpa/nameser.h> -#include <sys/socket.h> -#include <errno.h> -#ifdef HAVE_LBER_H -#include <lber.h> -#endif -#ifdef HAVE_LDAP_H -#include <ldap.h> -#endif -#if defined(HAVE_THREAD_H) -#include <thread.h> -#elif defined(HAVE_PTHREAD_H) -#include <pthread.h> -#endif - -#include "ldap-nss.h" -#include "util.h" -#include "common.h" -#include "log.h" - -#if defined(HAVE_USERSEC_H) -#define MAXALIASES 35 -#define MAXADDRSIZE 4 -#endif /* HAVE_USERSEC_H */ - -/* write a single network entry to the stream */ -static int write_netent(FILE *fp,struct netent *result) -{ - int32_t tmpint32,tmp2int32,tmp3int32; - /* write the network name */ - WRITE_STRING(fp,result->n_name); - /* write the alias list */ - WRITE_STRINGLIST_NULLTERM(fp,result->n_aliases); - /* write the number of addresses */ - WRITE_INT32(fp,1); - /* write the addresses in network byte order */ - WRITE_INT32(fp,result->n_addrtype); - WRITE_INT32(fp,sizeof(unsigned long int)); - result->n_net=htonl(result->n_net); - WRITE_INT32(fp,result->n_net); - return 0; -} -static enum nss_status -_nss_ldap_parse_net (LDAPMessage * e, - struct ldap_state * pvt, - void *result, char *buffer, size_t buflen) -{ - - char *tmp; - struct netent *network = (struct netent *) result; - enum nss_status stat; - - /* IPv6 support ? XXX */ - network->n_addrtype = AF_INET; - - stat = _nss_ldap_assign_attrval (e, ATM (LM_NETWORKS, cn), &network->n_name, - &buffer, &buflen); - if (stat != NSS_STATUS_SUCCESS) - return stat; - - stat = - _nss_ldap_assign_attrval (e, AT (ipNetworkNumber), &tmp, &buffer, - &buflen); - if (stat != NSS_STATUS_SUCCESS) - return stat; - - network->n_net = inet_network (tmp); - - stat = - _nss_ldap_assign_attrvals (e, ATM (LM_NETWORKS, cn), network->n_name, - &network->n_aliases, &buffer, &buflen, NULL); - if (stat != NSS_STATUS_SUCCESS) - return stat; - - return NSS_STATUS_SUCCESS; -} - -int nslcd_network_byname(FILE *fp) -{ - int32_t tmpint32; - char *name; - struct ldap_args a; - int retv; - struct netent result; - char buffer[1024]; - int errnop; - /* read request parameters */ - READ_STRING_ALLOC(fp,name); - /* log call */ - log_log(LOG_DEBUG,"nslcd_network_byname(%s)",name); - /* write the response header */ - /* FIXME: free(name) when one of these writes fails */ - WRITE_INT32(fp,NSLCD_VERSION); - WRITE_INT32(fp,NSLCD_ACTION_NETWORK_BYNAME); - /* do the LDAP request */ - LA_INIT(a); - LA_STRING(a)=name; - LA_TYPE(a)=LA_TYPE_STRING; - retv=nss2nslcd(_nss_ldap_getbyname(&a,&result,buffer,1024,&errnop,_nss_ldap_filt_getnetbyname,LM_NETWORKS,_nss_ldap_parse_net)); - /* no more need for this string */ - free(name); - /* write the response */ - WRITE_INT32(fp,retv); - if (retv==NSLCD_RESULT_SUCCESS) - write_netent(fp,&result); - WRITE_FLUSH(fp); - /* we're done */ - return 0; -} - -int nslcd_network_byaddr(FILE *fp) -{ - int32_t tmpint32; - int af; - int len; - char addr[64],name[1024]; - struct ldap_args a; - int retv=456; - struct netent result; - char buffer[1024]; - int errnop; - /* read address family */ - READ_INT32(fp,af); - if (af!=AF_INET) - { - log_log(LOG_WARNING,"incorrect address family specified: %d",af); - return -1; - } - /* read address length */ - READ_INT32(fp,len); - if ((len>64)||(len<=0)) - { - log_log(LOG_WARNING,"address length incorrect: %d",len); - return -1; - } - /* read address */ - READ(fp,addr,len); - /* translate the address to a string */ - if (inet_ntop(af,addr,name,1024)==NULL) - { - log_log(LOG_WARNING,"unable to convert address to string"); - return -1; - } - /* log call */ - log_log(LOG_DEBUG,"nslcd_network_byaddr(%s)",name); - /* write the response header */ - WRITE_INT32(fp,NSLCD_VERSION); - WRITE_INT32(fp,NSLCD_ACTION_NETWORK_BYADDR); - /* prepare the LDAP request */ - LA_INIT(a); - LA_STRING(a)=name; - LA_TYPE(a)=LA_TYPE_STRING; - /* do requests until we find a result */ - /* TODO: probably do more sofisticated queries */ - while (retv==456) - { - /* do the request */ - retv=nss2nslcd(_nss_ldap_getbyname(&a,&result,buffer,1024,&errnop,_nss_ldap_filt_getnetbyaddr,LM_NETWORKS,_nss_ldap_parse_net)); - /* if no entry was found, retry with .0 stripped from the end */ - if ((retv==NSLCD_RESULT_NOTFOUND) && - (strlen(name)>2) && - (strncmp(name+strlen(name)-2,".0",2)==0)) - { - /* strip .0 and try again */ - name[strlen(name)-2]='\0'; - retv=456; - } - } - /* write the response */ - WRITE_INT32(fp,retv); - if (retv==NSLCD_RESULT_SUCCESS) - write_netent(fp,&result); - WRITE_FLUSH(fp); - /* we're done */ - return 0; -} - -int nslcd_network_all(FILE *fp) -{ - int32_t tmpint32; - static struct ent_context *net_context; - /* these are here for now until we rewrite the LDAP code */ - struct netent result; - char buffer[1024]; - int errnop; - int retv; - /* log call */ - log_log(LOG_DEBUG,"nslcd_network_all()"); - /* write the response header */ - WRITE_INT32(fp,NSLCD_VERSION); - WRITE_INT32(fp,NSLCD_ACTION_NETWORK_ALL); - /* initialize context */ - if (_nss_ldap_ent_context_init(&net_context)==NULL) - return -1; - /* loop over all results */ - while ((retv=nss2nslcd(_nss_ldap_getent(&net_context,&result,buffer,1024,&errnop,_nss_ldap_filt_getnetent,LM_NETWORKS,_nss_ldap_parse_net)))==NSLCD_RESULT_SUCCESS) - { - /* write the result */ - WRITE_INT32(fp,retv); - if (retv==NSLCD_RESULT_SUCCESS) - write_netent(fp,&result); - } - /* write the final result code */ - WRITE_INT32(fp,retv); - WRITE_FLUSH(fp); - /* FIXME: if a previous call returns what happens to the context? */ - _nss_ldap_enter(); - _nss_ldap_ent_context_release(net_context); - _nss_ldap_leave(); - /* we're done */ - return 0; -} diff --git a/server/nslcd.c b/server/nslcd.c deleted file mode 100644 index 48db1cf..0000000 --- a/server/nslcd.c +++ /dev/null @@ -1,656 +0,0 @@ -/* - nslcd.c - ldap local connection daemon - - Copyright (C) 2006 West Consulting - Copyright (C) 2006 Arthur de Jong - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1301 USA -*/ - -#include "config.h" - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <stdint.h> -#include <sys/types.h> -#include <sys/param.h> -#include <sys/wait.h> -#ifdef HAVE_GETOPT_H -#include <getopt.h> -#endif /* HAVE_GETOPT_H */ -#include <assert.h> -#include <signal.h> -#include <errno.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/stat.h> -#include <sys/socket.h> -#include <sys/un.h> -#ifdef HAVE_GRP_H -#include <grp.h> -#endif /* HAVE_GRP_H */ -#include <nss.h> -#include <pthread.h> - -#include "nslcd.h" -#include "log.h" -#include "common.h" - - -/* the definition of the environment */ -extern char **environ; - - -/* flag to indictate if we are in debugging mode */ -static int nslcd_debugging=0; - - -/* the exit flag to indicate that a signal was received */ -static volatile int nslcd_exitsignal=0; - - -/* the server socket used for communication */ -static int nslcd_serversocket=-1; - - -/* thread ids of all running threads */ -#define NUM_THREADS 5 -pthread_t nslcd_threads[NUM_THREADS]; - - -/* display version information */ -static void display_version(FILE *fp) -{ - fprintf(fp,"%s\n",PACKAGE_STRING); - fprintf(fp,"Written by Luke Howard and Arthur de Jong.\n\n"); - fprintf(fp,"Copyright (C) 1997-2006 Luke Howard, Arthur de Jong and West Consulting\n" - "This is free software; see the source for copying conditions. There is NO\n" - "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"); -} - - -/* display usage information to stdout and exit(status) */ -static void display_usage(FILE *fp,const char *program_name) -{ - fprintf(fp,"Usage: %s [OPTION]...\n",program_name); - fprintf(fp,"Name Service LDAP connection daemon.\n"); - fprintf(fp," -d, --debug don't fork and print debugging to stderr\n"); - fprintf(fp," --help display this help and exit\n"); - fprintf(fp," --version output version information and exit\n"); - fprintf(fp,"\n" - "Report bugs to <%s>.\n",PACKAGE_BUGREPORT); -} - - -/* the definition of options for getopt(). see getopt(2) */ -static struct option const nslcd_options[] = -{ - { "debug", no_argument, NULL, 'd' }, - { "help", no_argument, NULL, 'h' }, - { "version", no_argument, NULL, 'V' }, - { NULL, 0, NULL, 0 } -}; -#define NSLCD_OPTIONSTRING "dhV" - - -/* parse command line options and save settings in struct */ -static void parse_cmdline(int argc,char *argv[]) -{ - int optc; - while ((optc=getopt_long(argc,argv,NSLCD_OPTIONSTRING,nslcd_options,NULL))!=-1) - { - switch (optc) - { - case 'd': /* -d, --debug don't fork and print debugging to stderr */ - nslcd_debugging=1; - log_setdefaultloglevel(LOG_DEBUG); - break; - case 'h': /* --help display this help and exit */ - display_usage(stdout,argv[0]); - exit(0); - case 'V': /* --version output version information and exit */ - display_version(stdout); - exit(0); - case ':': /* missing required parameter */ - case '?': /* unknown option character or extraneous parameter */ - default: - fprintf(stderr,"Try `%s --help' for more information.\n", - argv[0]); - exit(1); - } - } - /* check for remaining arguments */ - if (optind<argc) - { - fprintf(stderr,"%s: unrecognized option `%s'\n", - argv[0],argv[optind]); - fprintf(stderr,"Try `%s --help' for more information.\n", - argv[0]); - exit(1); - } -} - - -/* get a name of a signal with a given signal number */ -static const char *signame(int signum) -{ - switch (signum) - { - case SIGHUP: return "SIGHUP"; /* Hangup detected */ - case SIGINT: return "SIGINT"; /* Interrupt from keyboard */ - case SIGQUIT: return "SIGQUIT"; /* Quit from keyboard */ - case SIGILL: return "SIGILL"; /* Illegal Instruction */ - case SIGABRT: return "SIGABRT"; /* Abort signal from abort(3) */ - case SIGFPE: return "SIGFPE"; /* Floating point exception */ - case SIGKILL: return "SIGKILL"; /* Kill signal */ - case SIGSEGV: return "SIGSEGV"; /* Invalid memory reference */ - case SIGPIPE: return "SIGPIPE"; /* Broken pipe */ - case SIGALRM: return "SIGALRM"; /* Timer signal from alarm(2) */ - case SIGTERM: return "SIGTERM"; /* Termination signal */ - case SIGUSR1: return "SIGUSR1"; /* User-defined signal 1 */ - case SIGUSR2: return "SIGUSR2"; /* User-defined signal 2 */ - case SIGCHLD: return "SIGCHLD"; /* Child stopped or terminated */ - case SIGCONT: return "SIGCONT"; /* Continue if stopped */ - case SIGSTOP: return "SIGSTOP"; /* Stop process */ - case SIGTSTP: return "SIGTSTP"; /* Stop typed at tty */ - case SIGTTIN: return "SIGTTIN"; /* tty input for background process */ - case SIGTTOU: return "SIGTTOU"; /* tty output for background process */ -#ifdef SIGBUS - case SIGBUS: return "SIGBUS"; /* Bus error */ -#endif -#ifdef SIGPOLL - case SIGPOLL: return "SIGPOLL"; /* Pollable event */ -#endif -#ifdef SIGPROF - case SIGPROF: return "SIGPROF"; /* Profiling timer expired */ -#endif -#ifdef SIGSYS - case SIGSYS: return "SIGSYS"; /* Bad argument to routine */ -#endif -#ifdef SIGTRAP - case SIGTRAP: return "SIGTRAP"; /* Trace/breakpoint trap */ -#endif -#ifdef SIGURG - case SIGURG: return "SIGURG"; /* Urgent condition on socket */ -#endif -#ifdef SIGVTALRM - case SIGVTALRM: return "SIGVTALRM"; /* Virtual alarm clock */ -#endif -#ifdef SIGXCPU - case SIGXCPU: return "SIGXCPU"; /* CPU time limit exceeded */ -#endif -#ifdef SIGXFSZ - case SIGXFSZ: return "SIGXFSZ"; /* File size limit exceeded */ -#endif - default: return "UNKNOWN"; - } -} - - -/* signal handler for closing down */ -static RETSIGTYPE sigexit_handler(int signum) -{ - int i; - nslcd_exitsignal=signum; - /* cancel all running threads */ - for (i=0;i<NUM_THREADS;i++) - pthread_cancel(nslcd_threads[i]); - -} - - -/* do some cleaning up before terminating */ -static void exithandler(void) -{ - /* close socket if it's still in use */ - if (nslcd_serversocket >= 0) - { - if (close(nslcd_serversocket)) - log_log(LOG_WARNING,"problem closing server socket (ignored): %s",strerror(errno)); - } - /* remove existing named socket */ - if (unlink(NSLCD_SOCKET)<0) - { - log_log(LOG_DEBUG,"unlink() of "NSLCD_SOCKET" failed (ignored): %s", - strerror(errno)); - } - /* remove pidfile */ - if (unlink(NSLCD_PIDFILE)<0) - { - log_log(LOG_DEBUG,"unlink() of "NSLCD_PIDFILE" failed (ignored): %s", - strerror(errno)); - } - /* log exit */ - log_log(LOG_INFO,"version %s bailing out",VERSION); -} - - -/* returns a socket ready to answer requests from the client, - exit()s on error */ -static int open_socket(void) -{ - int sock; - struct sockaddr_un addr; - - /* create a socket */ - if ( (sock=socket(PF_UNIX,SOCK_STREAM,0))<0 ) - { - log_log(LOG_ERR,"cannot create socket: %s",strerror(errno)); - exit(1); - } - - /* remove existing named socket */ - if (unlink(NSLCD_SOCKET)<0) - { - log_log(LOG_DEBUG,"unlink() of "NSLCD_SOCKET" failed (ignored): %s", - strerror(errno)); - } - - /* create socket address structure */ - memset(&addr,0,sizeof(struct sockaddr_un)); - addr.sun_family=AF_UNIX; - strcpy(addr.sun_path,NSLCD_SOCKET); - - /* bind to the named socket */ - if (bind(sock,(struct sockaddr *)&addr,sizeof(struct sockaddr_un))) - { - log_log(LOG_ERR,"bind() to "NSLCD_SOCKET" failed: %s", - strerror(errno)); - if (close(sock)) - log_log(LOG_WARNING,"problem closing socket: %s",strerror(errno)); - exit(1); - } - - /* close the file descriptor on exit */ - if (fcntl(sock,F_SETFD,FD_CLOEXEC)<0) - { - log_log(LOG_ERR,"fctnl(F_SETFL,O_NONBLOCK) failed: %s",strerror(errno)); - if (close(sock)) - log_log(LOG_WARNING,"problem closing socket: %s",strerror(errno)); - exit(1); - } - - /* set permissions of socket so anybody can do requests */ - if (chmod(NSLCD_SOCKET,0666)) - { - log_log(LOG_ERR,"fctnl(F_SETFL,O_NONBLOCK) failed: %s",strerror(errno)); - if (close(sock)) - log_log(LOG_WARNING,"problem closing socket: %s",strerror(errno)); - exit(1); - } - - /* start listening for connections */ - if (listen(sock,SOMAXCONN)<0) - { - log_log(LOG_ERR,"listen() failed: %s",strerror(errno)); - if (close(sock)) - log_log(LOG_WARNING,"problem closing socket: %s",strerror(errno)); - exit(1); - } - - /* we're done */ - return sock; -} - -/* read the version information and action from the stream - this function returns the read action in location pointer to by action */ -static int read_header(FILE *fp,int32_t *action) -{ - int32_t tmpint32; - /* read the protocol version */ - READ_TYPE(fp,tmpint32,int32_t); - if (tmpint32 != NSLCD_VERSION) - { - log_log(LOG_DEBUG,"wrong nslcd version id (%d)",(int)tmpint32); - return -1; - } - /* read the request type */ - READ(fp,action,sizeof(int32_t)); - return 0; -} - -/* read a request message, returns <0 in case of errors, - this function closes the socket */ -static void handleconnection(int sock) -{ - FILE *fp; - socklen_t alen; - struct ucred client; - int32_t action; - - /* look up process information from client */ - alen=sizeof(struct ucred); - if (getsockopt(sock,SOL_SOCKET,SO_PEERCRED,&client,&alen) < 0) - { - log_log(LOG_ERR,"getsockopt(SO_PEERCRED) failed: %s",strerror(errno)); - if (close(sock)) - log_log(LOG_WARNING,"problem closing socket: %s",strerror(errno)); - return; - } - - /* log connection */ - log_log(LOG_DEBUG,"connection from pid=%d uid=%d gid=%d", - (int)client.pid,(int)client.uid,(int)client.gid); - - /* create a stream object */ - if ((fp=fdopen(sock,"w+"))==NULL) - { - log_log(LOG_WARNING,"cannot create stream for writing: %s",strerror(errno)); - close(sock); - return; - } - - /* read request */ - if (read_header(fp,&action)) - { - fclose(fp); - return; - } - - /* handle request */ - switch (action) - { - case NSLCD_ACTION_ALIAS_BYNAME: nslcd_alias_byname(fp); break; - case NSLCD_ACTION_ALIAS_ALL: nslcd_alias_all(fp); break; - case NSLCD_ACTION_ETHER_BYNAME: nslcd_ether_byname(fp); break; - case NSLCD_ACTION_ETHER_BYETHER: nslcd_ether_byether(fp); break; - case NSLCD_ACTION_ETHER_ALL: nslcd_ether_all(fp); break; - case NSLCD_ACTION_GROUP_BYNAME: nslcd_group_byname(fp); break; - case NSLCD_ACTION_GROUP_BYGID: nslcd_group_bygid(fp); break; - case NSLCD_ACTION_GROUP_BYMEMBER: nslcd_group_bymember(fp); break; - case NSLCD_ACTION_GROUP_ALL: nslcd_group_all(fp); break; - case NSLCD_ACTION_HOST_BYNAME: nslcd_host_byname(fp); break; - case NSLCD_ACTION_HOST_BYADDR: nslcd_host_byaddr(fp); break; - case NSLCD_ACTION_HOST_ALL: nslcd_host_all(fp); break; - case NSLCD_ACTION_NETGROUP_BYNAME: nslcd_netgroup_byname(fp); break; - case NSLCD_ACTION_NETWORK_BYNAME: nslcd_network_byname(fp); break; - case NSLCD_ACTION_NETWORK_BYADDR: nslcd_network_byaddr(fp); break; - case NSLCD_ACTION_NETWORK_ALL: nslcd_network_all(fp); break; - case NSLCD_ACTION_PASSWD_BYNAME: nslcd_passwd_byname(fp); break; - case NSLCD_ACTION_PASSWD_BYUID: nslcd_passwd_byuid(fp); break; - case NSLCD_ACTION_PASSWD_ALL: nslcd_passwd_all(fp); break; - case NSLCD_ACTION_PROTOCOL_BYNAME: nslcd_protocol_byname(fp); break; - case NSLCD_ACTION_PROTOCOL_BYNUMBER:nslcd_protocol_bynumber(fp); break; - case NSLCD_ACTION_PROTOCOL_ALL: nslcd_protocol_all(fp); break; - case NSLCD_ACTION_RPC_BYNAME: nslcd_rpc_byname(fp); break; - case NSLCD_ACTION_RPC_BYNUMBER: nslcd_rpc_bynumber(fp); break; - case NSLCD_ACTION_RPC_ALL: nslcd_rpc_all(fp); break; - case NSLCD_ACTION_SERVICE_BYNAME: nslcd_service_byname(fp); break; - case NSLCD_ACTION_SERVICE_BYNUMBER: nslcd_service_bynumber(fp); break; - case NSLCD_ACTION_SERVICE_ALL: nslcd_service_all(fp); break; - case NSLCD_ACTION_SHADOW_BYNAME: nslcd_shadow_byname(fp); break; - case NSLCD_ACTION_SHADOW_ALL: nslcd_shadow_all(fp); break; - default: - log_log(LOG_WARNING,"invalid request id: %d",(int)action); - break; - } - - /* we're done with the request */ - fclose(fp); - return; -} - -/* accept a connection on the socket */ -static void acceptconnection(void) -{ - int csock; - int j; - struct sockaddr_storage addr; - socklen_t alen; - - /* accept a new connection */ - alen=(socklen_t)sizeof(struct sockaddr_storage); - csock=accept(nslcd_serversocket,(struct sockaddr *)&addr,&alen); - if (csock<0) - { - if ((errno==EINTR)||(errno==EAGAIN)||(errno==EWOULDBLOCK)) - { - log_log(LOG_DEBUG,"debug: accept() failed (ignored): %s",strerror(errno)); - return; - } - log_log(LOG_ERR,"accept() failed: %s",strerror(errno)); - return; - } - - /* make sure O_NONBLOCK is not inherited */ - if ((j=fcntl(csock,F_GETFL,0))<0) - { - log_log(LOG_ERR,"fctnl(F_GETFL) failed: %s",strerror(errno)); - if (close(csock)) - log_log(LOG_WARNING,"problem closing socket: %s",strerror(errno)); - return; - } - if (fcntl(csock,F_SETFL,j&~O_NONBLOCK)<0) - { - log_log(LOG_ERR,"fctnl(F_SETFL,~O_NONBLOCK) failed: %s",strerror(errno)); - if (close(csock)) - log_log(LOG_WARNING,"problem closing socket: %s",strerror(errno)); - return; - } - - /* handle the connection */ - handleconnection(csock); -} - - -/* write the current process id to the specified file */ -static void write_pidfile(const char *filename) -{ - FILE *fp; - if (filename!=NULL) - { - if ((fp=fopen(filename,"w"))==NULL) - { - log_log(LOG_ERR,"cannot open pid file (%s): %s",filename,strerror(errno)); - exit(1); - } - if (fprintf(fp,"%d\n",(int)getpid())<=0) - { - log_log(LOG_ERR,"error writing pid file (%s)",filename); - exit(1); - } - if (fclose(fp)) - { - log_log(LOG_ERR,"error writing pid file (%s): %s",filename,strerror(errno)); - exit(1); - } - } -} - - -/* try to install signal handler and check result */ -static void install_sighandler(int signum,RETSIGTYPE (*handler) (int)) -{ - struct sigaction act; - memset(&act,0,sizeof(struct sigaction)); - act.sa_handler=handler; - sigemptyset(&act.sa_mask); - act.sa_flags=SA_RESTART|SA_NOCLDSTOP; - if (sigaction(signum,&act,NULL)!=0) - { - log_log(LOG_ERR,"error installing signal handler for '%s': %s",signame(signum),strerror(errno)); - exit(1); - } -} - -static void *worker(void *arg) -{ - /* start waiting for incoming connections */ - while (nslcd_exitsignal==0) - { - /* wait for a new connection */ - acceptconnection(); - } - return NULL; -} - - -/* the main program... */ -int main(int argc,char *argv[]) -{ - gid_t mygid=-1; - uid_t myuid=-1; - int i; - - /* parse the command line */ - parse_cmdline(argc,argv); - - /* clear the environment */ - /* TODO:implement */ - - /* check if we are already running */ - /* FIXME: implement (maybe pass along options or commands) */ - - /* disable ldap lookups of host names to avoid lookup loop - and fall back to files dns (a sensible default) */ - /* TODO: parse /etc/nsswitch ourselves and just remove ldap from the list */ - if (__nss_configure_lookup("hosts","files dns")) - log_log(LOG_ERR,"unable to override hosts lookup method: %s",strerror(errno)); - - /* daemonize */ - if ((!nslcd_debugging)&&(daemon(0,0)<0)) - { - log_log(LOG_ERR,"unable to daemonize: %s",strerror(errno)); - exit(1); - } - - /* set default mode for pidfile and socket */ - umask(0022); - - /* intilialize logging */ - if (!nslcd_debugging) - log_startlogging(); - log_log(LOG_INFO,"version %s starting",VERSION); - - /* install handler to close stuff off on exit and log notice */ - atexit(exithandler); - - /* write pidfile */ - write_pidfile(NSLCD_PIDFILE); - - /* create socket */ - nslcd_serversocket=open_socket(); - -#ifdef HAVE_SETGROUPS - /* drop all supplemental groups */ - if (setgroups(0,NULL)<0) - { - log_log(LOG_WARNING,"cannot setgroups(0,NULL) (ignored): %s",strerror(errno)); - } - else - { - log_log(LOG_DEBUG,"debug: setgroups(0,NULL) done"); - } -#else /* HAVE_SETGROUPS */ - log_log(LOG_DEBUG,"debug: setgroups() not available"); -#endif /* not HAVE_SETGROUPS */ - -#ifdef USE_CAPABILITIES - /* if we are using capbilities, set them to be kept - across setuid() calls so we can limit them later on */ - if (prctl(PR_SET_KEEPCAPS,1)) - { - log_log(LOG_ERR,"cannot prctl(PR_SET_KEEPCAPS,1): %s",strerror(errno)); - exit(1); - } - log_log(LOG_DEBUG,"debug: prctl(PR_SET_KEEPCAPS,1) done"); - /* dump the current capabilities */ - caps=cap_get_proc(); - log_log(LOG_DEBUG,"debug: current capabilities: %s",cap_to_text(caps,NULL)); - cap_free(caps); -#endif /* USE_CAPABILITIES */ - - /* change to nslcd gid */ - if (mygid!=((gid_t)-1)) - { - if (setgid(mygid)!=0) - { - log_log(LOG_ERR,"cannot setgid(%d): %s",(int)mygid,strerror(errno)); - exit(1); - } - log_log(LOG_DEBUG,"debug: setgid(%d) done",mygid); - } - - /* change to nslcd uid */ - if (myuid!=((uid_t)-1)) - { - if (setuid(myuid)!=0) - { - log_log(LOG_ERR,"cannot setuid(%d): %s",(int)myuid,strerror(errno)); - exit(1); - } - log_log(LOG_DEBUG,"debug: setuid(%d) done",myuid); - } - -#ifdef USE_CAPABILITIES - /* limit the capabilities */ - if (cap_set_proc(mycapabilities)!=0) - { - log_log(LOG_ERR,"cannot cap_set_proc(%s): %s",cap_to_text(mycapabilities,NULL),strerror(errno)); - exit(1); - } - log_log(LOG_DEBUG,"debug: cap_set_proc(%2) done",cap_to_text(mycapabilities,NULL)); - /* we no longer need this so we should free it */ - cap_free(mycapabilities); - /* dump the current capabilities */ - caps=cap_get_proc(); - log_log(LOG_DEBUG,"debug: current capabilities: %s",cap_to_text(caps,NULL)); - cap_free(caps); -#endif /* USE_CAPABILITIES */ - - /* install signalhandlers for some signals */ - install_sighandler(SIGHUP, sigexit_handler); - install_sighandler(SIGINT, sigexit_handler); - install_sighandler(SIGQUIT,sigexit_handler); - install_sighandler(SIGABRT,sigexit_handler); - install_sighandler(SIGPIPE,SIG_IGN); - install_sighandler(SIGTERM,sigexit_handler); - install_sighandler(SIGUSR1,sigexit_handler); - install_sighandler(SIGUSR2,sigexit_handler); - /* TODO: install signal handlers for reloading configuration */ - - log_log(LOG_INFO,"accepting connections"); - - /* start worker threads */ - for (i=0;i<NUM_THREADS;i++) - { - if (pthread_create(&nslcd_threads[i],NULL,worker,NULL)) - { - log_log(LOG_ERR,"unable to start worker thread %d: %s",i,strerror(errno)); - exit(1); - } - } - - /* wait for all threads to die */ - for (i=0;i<NUM_THREADS;i++) - { - if (pthread_join(nslcd_threads[i],NULL)) - { - log_log(LOG_ERR,"unable to wait for worker thread %d: %s",i,strerror(errno)); - exit(1); - } - } - - /* print something about received signals */ - if (nslcd_exitsignal!=0) - { - log_log(LOG_INFO,"caught signal %s (%d), shutting down", - signame(nslcd_exitsignal),nslcd_exitsignal); - } - - return 1; -} diff --git a/server/pagectrl.c b/server/pagectrl.c deleted file mode 100644 index ca439dd..0000000 --- a/server/pagectrl.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - pagectrl.c - provide a replacement ldap_create_page_control() function. - This file was part of the nss_ldap library which has been - forked into the nss-ldapd library. - - Copyright (C) 2002 Max Caines - This software is not subject to any license of the University - of Wolverhampton. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1301 USA -*/ - -/* TODO: move this to compat/ and add it only when needed */ -/* Note: this is only used in ldap-nss.c */ - -#include "config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <lber.h> -#include <ldap.h> - -#include "pagectrl.h" - -#ifndef LDAP_CONTROL_PAGE_OID -#define LDAP_CONTROL_PAGE_OID "1.2.840.113556.1.4.319" -#endif - -#ifndef HAVE_LDAP_CREATE_CONTROL -#error LDAP client library does not support ldap_create_control() -#endif - -#ifndef HAVE_LDAP_CREATE_PAGE_CONTROL -/*--- - ldap_create_page_control - - Create and encode the Paged Results control. - - ld (IN) An LDAP session handle, as obtained from a call to - ldap_init(). - - pagesize (IN) The number of entries to return in each page - - cookiep (IN) Pointer to a berVal structure that the server uses to - determine the current location in the - result set (opaque). Set to NULL the - first time. - - iscritical (IN) Is this control critical to the search? - - ctrlp (OUT) A result parameter that will be assigned the address - of an LDAPControl structure that contains the - PagedResult control created by this function. - The memory occupied by the LDAPControl structure - SHOULD be freed when it is no longer in use by - calling ldap_control_free(). - - - Ber encoding - - PageResult ::= SEQUENCE { - pageSize INTEGER - cookie OCTET STRING } - - - Note: The first time the Page control is created, the cookie - should be set to a zero-length string. The cookie obtained - from calling ldap_parse_page_control() should be used as - the cookie in the next ldap_create_page_control call. - - ---*/ - -int -ldap_create_page_control (LDAP * ld, - unsigned long pagesize, - struct berval *cookiep, - int iscritical, LDAPControl ** ctrlp) -{ - ber_tag_t tag; - BerElement *ber; - BerElement *ldap_alloc_ber_with_options (LDAP * ld); - int rc; - - if ((ld == NULL) || (ctrlp == NULL)) - { - return (LDAP_PARAM_ERROR); - } - - if ((ber = ldap_alloc_ber_with_options (ld)) == NULL) - { - return (LDAP_NO_MEMORY); - } - - tag = ber_printf (ber, "{i", pagesize); - if (tag == LBER_ERROR) - goto exit; - - if (cookiep == NULL) - tag = ber_printf (ber, "o", "", 0); - else - tag = ber_printf (ber, "O", cookiep); - if (tag == LBER_ERROR) - goto exit; - - tag = ber_printf (ber, /*{ */ "N}"); - if (tag == LBER_ERROR) - goto exit; - - rc = ldap_create_control (LDAP_CONTROL_PAGE_OID, ber, iscritical, ctrlp); - - ber_free (ber, 1); - return (rc); - -exit: - ber_free (ber, 1); - return (LDAP_ENCODING_ERROR); -} -#endif /* HAVE_LDAP_CREATE_PAGE_CONTROL */ - -#ifndef HAVE_LDAP_PARSE_PAGE_CONTROL -/*--- - ldap_parse_page_control - - Decode the Virtual List View control return information. - - ld (IN) An LDAP session handle. - - ctrls (IN) The address of a NULL-terminated array of - LDAPControl structures, typically obtained - by a call to ldap_parse_result(). - - list_countp (OUT) This result parameter is filled in with the number - of entries returned in this page - - cookiep (OUT) This result parameter is filled in with the address - of a struct berval that contains the server- - generated cookie. - The returned cookie SHOULD be used in the next call - to create a Page sort control. The struct berval - returned SHOULD be disposed of by calling ber_bvfree() - when it is no longer needed. - ----*/ -int -ldap_parse_page_control (LDAP * ld, - LDAPControl ** ctrls, - unsigned long *list_countp, struct berval **cookiep) -{ - BerElement *ber; - LDAPControl *pControl; - int i; - unsigned long count; - ber_tag_t tag; - - if (cookiep) - { - *cookiep = NULL; /* Make sure we return a NULL if error occurs. */ - } - - if (ld == NULL) - { - return (LDAP_PARAM_ERROR); - } - - if (ctrls == NULL) - { - return (LDAP_CONTROL_NOT_FOUND); - } - - /* Search the list of control responses for a Page control. */ - for (i = 0; ctrls[i]; i++) - { - pControl = ctrls[i]; - if (!strcmp (LDAP_CONTROL_PAGE_OID, pControl->ldctl_oid)) - goto foundPageControl; - } - - /* No page control was found. */ - return (LDAP_CONTROL_NOT_FOUND); - -foundPageControl: - /* Create a BerElement from the berval returned in the control. */ - ber = ber_init (&pControl->ldctl_value); - - if (ber == NULL) - { - return (LDAP_NO_MEMORY); - } - - /* Extract the data returned in the control. */ - tag = ber_scanf (ber, "{iO" /*} */ , &count, cookiep); - - if (tag == LBER_ERROR) - { - ber_free (ber, 1); - return (LDAP_DECODING_ERROR); - } - - ber_free (ber, 1); - - /* Return data to the caller for items that were requested. */ - if (list_countp) - { - *list_countp = count; - } - - return (LDAP_SUCCESS); -} -#endif /* HAVE_LDAP_PARSE_PAGE_CONTROL */ diff --git a/server/pagectrl.h b/server/pagectrl.h deleted file mode 100644 index c678ca9..0000000 --- a/server/pagectrl.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - pagectrl.h - provide a replacement ldap_create_page_control() function. - This file was part of the nss_ldap library which has been - forked into the nss-ldapd library. - - Copyright (C) 1997-2005 Luke Howard - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1301 USA -*/ - -#ifndef _LDAP_NSS_LDAP_PAGECTRL_H -#define _LDAP_NSS_LDAP_PAGECTRL_H - -#ifndef HAVE_LDAP_CREATE_PAGE_CONTROL -int -ldap_create_page_control( LDAP *ld, - unsigned long pagesize, - struct berval *cookiep, - int iscritical, - LDAPControl **ctrlp ); -#endif /* HAVE_LDAP_CREATE_PAGE_CONTROL */ - -#ifndef HAVE_LDAP_PARSE_PAGE_CONTROL -int -ldap_parse_page_control( - LDAP *ld, - LDAPControl **ctrls, - unsigned long *list_countp, - struct berval **cookiep ); -#endif /* HAVE_LDAP_PARSE_PAGE_CONTROL */ - -#endif /* _LDAP_NSS_LDAP_UTIL_H */ diff --git a/server/passwd.c b/server/passwd.c deleted file mode 100644 index abdb104..0000000 --- a/server/passwd.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - passwd.c - password entry lookup routines - This file was part of the nss_ldap library (as ldap-pwd.c) - which has been forked into the nss-ldapd library. - - Copyright (C) 1997-2005 Luke Howard - Copyright (C) 2006 West Consulting - Copyright (C) 2006 Arthur de Jong - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1301 USA -*/ - -#include "config.h" - -#include <stdlib.h> -#include <sys/types.h> -#include <sys/param.h> -#include <string.h> -#include <pwd.h> -#include <errno.h> -#ifdef HAVE_LBER_H -#include <lber.h> -#endif -#ifdef HAVE_LDAP_H -#include <ldap.h> -#endif -#if defined(HAVE_THREAD_H) -#include <thread.h> -#elif defined(HAVE_PTHREAD_H) -#include <pthread.h> -#endif -#include <stdio.h> - -#include "ldap-nss.h" -#include "util.h" -#include "common.h" -#include "log.h" - -#ifndef UID_NOBODY -#define UID_NOBODY (-2) -#endif - -#ifndef GID_NOBODY -#define GID_NOBODY UID_NOBODY -#endif - - -static inline enum nss_status _nss_ldap_assign_emptystring( - char **valptr, char **buffer, size_t * buflen) -{ - if (*buflen < 2) - return NSS_STATUS_TRYAGAIN; - - *valptr = *buffer; - - **valptr = '\0'; - - (*buffer)++; - (*buflen)--; - - return NSS_STATUS_SUCCESS; -} - -static enum nss_status _nss_ldap_parse_pw (LDAPMessage * e, - struct ldap_state * pvt, - void *result, char *buffer, size_t buflen) -{ - struct passwd *pw = (struct passwd *) result; - char *uid, *gid; - enum nss_status stat; - char tmpbuf[ sizeof( uid_t ) * 8 / 3 + 2 ]; - size_t tmplen; - char *tmp; - - tmpbuf[ sizeof(tmpbuf) - 1 ] = '\0'; - - if (_nss_ldap_oc_check (e, "shadowAccount") == NSS_STATUS_SUCCESS) - { - /* don't include password for shadowAccount */ - if (buflen < 3) - return NSS_STATUS_TRYAGAIN; - - pw->pw_passwd = buffer; - strcpy (buffer, "x"); - buffer += 2; - buflen -= 2; - } - else - { - stat = - _nss_ldap_assign_userpassword (e, ATM (LM_PASSWD, userPassword), - &pw->pw_passwd, &buffer, &buflen); - if (stat != NSS_STATUS_SUCCESS) - return stat; - } - - stat = - _nss_ldap_assign_attrval (e, ATM (LM_PASSWD, uid), &pw->pw_name, &buffer, - &buflen); - if (stat != NSS_STATUS_SUCCESS) - return stat; - - tmp = tmpbuf; - tmplen = sizeof (tmpbuf) - 1; - stat = - _nss_ldap_assign_attrval (e, AT (uidNumber), &uid, &tmp, &tmplen); - if (stat != NSS_STATUS_SUCCESS) - return stat; - pw->pw_uid = (*uid == '\0') ? UID_NOBODY : (uid_t) atol (uid); - - tmp = tmpbuf; - tmplen = sizeof (tmpbuf) - 1; - stat = - _nss_ldap_assign_attrval (e, ATM (LM_PASSWD, gidNumber), &gid, &tmp, - &tmplen); - if (stat != NSS_STATUS_SUCCESS) - return stat; - pw->pw_gid = (*gid == '\0') ? GID_NOBODY : (gid_t) atol (gid); - - stat = - _nss_ldap_assign_attrval (e, AT (gecos), &pw->pw_gecos, &buffer, - &buflen); - if (stat != NSS_STATUS_SUCCESS) - { - pw->pw_gecos = NULL; - stat = - _nss_ldap_assign_attrval (e, ATM (LM_PASSWD, cn), &pw->pw_gecos, - &buffer, &buflen); - if (stat != NSS_STATUS_SUCCESS) - return stat; - } - - stat = - _nss_ldap_assign_attrval (e, AT (homeDirectory), &pw->pw_dir, &buffer, - &buflen); - if (stat != NSS_STATUS_SUCCESS) - (void) _nss_ldap_assign_emptystring (&pw->pw_dir, &buffer, &buflen); - - stat = - _nss_ldap_assign_attrval (e, AT (loginShell), &pw->pw_shell, &buffer, - &buflen); - if (stat != NSS_STATUS_SUCCESS) - (void) _nss_ldap_assign_emptystring (&pw->pw_shell, &buffer, &buflen); - - return NSS_STATUS_SUCCESS; -} - -/* macros for expanding the NSLCD_PASSWD macro */ -#define NSLCD_STRING(field) WRITE_STRING(fp,field) -#define NSLCD_TYPE(field,type) WRITE_TYPE(fp,field,type) -#define PASSWD_NAME result.pw_name -#define PASSWD_PASSWD result.pw_passwd -#define PASSWD_UID result.pw_uid -#define PASSWD_GID result.pw_gid -#define PASSWD_GECOS result.pw_gecos -#define PASSWD_DIR result.pw_dir -#define PASSWD_SHELL result.pw_shell - -/* the caller should take care of opening and closing the stream */ -int nslcd_passwd_byname(FILE *fp) -{ - int32_t tmpint32; - char *name; - /* these are here for now until we rewrite the LDAP code */ - struct passwd result; - char buffer[1024]; - int errnop; - int retv; - struct ldap_args a; - /* read request parameters */ - READ_STRING_ALLOC(fp,name); - /* FIXME: free() this buffer somewhere */ - /* log call */ - log_log(LOG_DEBUG,"nslcd_passwd_byname(%s)",name); - /* do the LDAP request */ - LA_INIT(a); - LA_STRING(a)=name; - LA_TYPE(a)=LA_TYPE_STRING; - retv=nss2nslcd(_nss_ldap_getbyname(&a,&result,buffer,1024,&errnop,_nss_ldap_filt_getpwnam,LM_PASSWD,_nss_ldap_parse_pw)); - /* no more need for this string */ - free(name); - /* write the response */ - WRITE_INT32(fp,NSLCD_VERSION); - WRITE_INT32(fp,NSLCD_ACTION_PASSWD_BYNAME); - WRITE_INT32(fp,retv); - if (retv==NSLCD_RESULT_SUCCESS) - { - NSLCD_PASSWD; - } - WRITE_FLUSH(fp); - /* we're done */ - return 0; -} - -int nslcd_passwd_byuid(FILE *fp) -{ - int32_t tmpint32; - uid_t uid; - /* these are here for now until we rewrite the LDAP code */ - struct passwd result; - char buffer[1024]; - int errnop; - int retv; - struct ldap_args a; - /* read request parameters */ - READ_TYPE(fp,uid,uid_t); - /* log call */ - log_log(LOG_DEBUG,"nslcd_passwd_byuid(%d)",(int)uid); - /* do the LDAP request */ - LA_INIT(a); - LA_NUMBER(a)=uid; - LA_TYPE(a)=LA_TYPE_NUMBER; - retv=nss2nslcd(_nss_ldap_getbyname(&a,&result,buffer,1024,&errnop,_nss_ldap_filt_getpwuid,LM_PASSWD,_nss_ldap_parse_pw)); - /* write the response */ - WRITE_INT32(fp,NSLCD_VERSION); - WRITE_INT32(fp,NSLCD_ACTION_PASSWD_BYUID); - WRITE_INT32(fp,retv); - if (retv==NSLCD_RESULT_SUCCESS) - { - NSLCD_PASSWD; - } - WRITE_FLUSH(fp); - /* we're done */ - return 0; -} - -int nslcd_passwd_all(FILE *fp) -{ - int32_t tmpint32; - /* these are here for now until we rewrite the LDAP code */ - struct ent_context *pw_context = NULL; - struct passwd result; - char buffer[1024]; - int errnop; - int retv; - /* log call */ - log_log(LOG_DEBUG,"nslcd_passwd_all()"); - /* write the response header */ - WRITE_INT32(fp,NSLCD_VERSION); - WRITE_INT32(fp,NSLCD_ACTION_PASSWD_ALL); - /* initialize context */ - if (_nss_ldap_ent_context_init(&pw_context)==NULL) - return -1; - /* go over results */ - while ((retv=nss2nslcd(_nss_ldap_getent(&pw_context,&result,buffer,1024,&errnop,_nss_ldap_filt_getpwent,LM_PASSWD,_nss_ldap_parse_pw)))==NSLCD_RESULT_SUCCESS) - { - /* write the result */ - WRITE_INT32(fp,retv); - NSLCD_PASSWD; - } - /* write the final result code */ - WRITE_INT32(fp,retv); - WRITE_FLUSH(fp); - /* FIXME: if some statement returns what happens to the context? */ - _nss_ldap_enter(); \ - _nss_ldap_ent_context_release(pw_context); \ - _nss_ldap_leave(); \ - /* we're done */ - return 0; -} diff --git a/server/protocol.c b/server/protocol.c deleted file mode 100644 index 71ce52d..0000000 --- a/server/protocol.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - protocol.c - network address entry lookup routines - This file was part of the nss_ldap library (as ldap-proto.c) - which has been forked into the nss-ldapd library. - - Copyright (C) 1997-2005 Luke Howard - Copyright (C) 2006 West Consulting - Copyright (C) 2006 Arthur de Jong - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1301 USA -*/ - -/* - Determine the canonical name of the RPC with _nss_ldap_getrdnvalue(), - and assign any values of "cn" which do NOT match this canonical name - as aliases. - */ - -#include "config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <netdb.h> -#include <errno.h> -#ifdef HAVE_LBER_H -#include <lber.h> -#endif -#ifdef HAVE_LDAP_H -#include <ldap.h> -#endif -#if defined(HAVE_THREAD_H) -#include <thread.h> -#elif defined(HAVE_PTHREAD_H) -#include <pthread.h> -#endif - -#include "ldap-nss.h" -#include "util.h" -#include "common.h" -#include "log.h" - -static enum nss_status _nss_ldap_parse_proto (LDAPMessage *e, - struct ldap_state *pvt, - void *result, char *buffer, size_t buflen) -{ - - struct protoent *proto = (struct protoent *) result; - char *number; - enum nss_status stat; - - stat = - _nss_ldap_getrdnvalue (e, ATM (LM_PROTOCOLS, cn), &proto->p_name, - &buffer, &buflen); - if (stat != NSS_STATUS_SUCCESS) - return stat; - - stat = - _nss_ldap_assign_attrval (e, AT (ipProtocolNumber), &number, &buffer, - &buflen); - if (stat != NSS_STATUS_SUCCESS) - return stat; - - proto->p_proto = atoi (number); - - stat = - _nss_ldap_assign_attrvals (e, ATM (LM_PROTOCOLS, cn), proto->p_name, - &proto->p_aliases, &buffer, &buflen, NULL); - if (stat != NSS_STATUS_SUCCESS) - return stat; - - return NSS_STATUS_SUCCESS; -} - -/* macros for expanding the NSLCD_PROTOCOL macro */ -#define NSLCD_STRING(field) WRITE_STRING(fp,field) -#define NSLCD_STRINGLIST(field) WRITE_STRINGLIST_NULLTERM(fp,field) -#define NSLCD_INT32(field) WRITE_INT32(fp,field) -#define PROTOCOL_NAME result.p_name -#define PROTOCOL_ALIASES result.p_aliases -#define PROTOCOL_NUMBER result.p_proto - -int nslcd_protocol_byname(FILE *fp) -{ - int32_t tmpint32,tmp2int32,tmp3int32; - char *name; - struct ldap_args a; - /* these are here for now until we rewrite the LDAP code */ - struct protoent result; - char buffer[1024]; - int errnop; - int retv; - /* read request parameters */ - READ_STRING_ALLOC(fp,name); - /* log call */ - log_log(LOG_DEBUG,"nslcd_protocol_byname(%s)",name); - /* write the response header */ - WRITE_INT32(fp,NSLCD_VERSION); - WRITE_INT32(fp,NSLCD_ACTION_PROTOCOL_BYNAME); - /* do the LDAP request */ - LA_INIT(a); - LA_STRING(a)=name; - LA_TYPE(a)=LA_TYPE_STRING; - retv=nss2nslcd(_nss_ldap_getbyname(&a,&result,buffer,1024,&errnop,_nss_ldap_filt_getprotobyname,LM_PROTOCOLS,_nss_ldap_parse_proto)); - /* no more need for this string */ - free(name); - /* write the response */ - WRITE_INT32(fp,retv); - if (retv==NSLCD_RESULT_SUCCESS) - { - NSLCD_PROTOCOL; - } - WRITE_FLUSH(fp); - /* we're done */ - return 0; -} - -int nslcd_protocol_bynumber(FILE *fp) -{ - int32_t tmpint32,tmp2int32,tmp3int32; - int protocol; - struct ldap_args a; - /* these are here for now until we rewrite the LDAP code */ - struct protoent result; - char buffer[1024]; - int errnop; - int retv; - /* read request parameters */ - READ_INT32(fp,protocol); - /* log call */ - log_log(LOG_DEBUG,"nslcd_protocol_bynumber(%d)",protocol); - /* write the response header */ - WRITE_INT32(fp,NSLCD_VERSION); - WRITE_INT32(fp,NSLCD_ACTION_PROTOCOL_BYNUMBER); - /* do the LDAP request */ - LA_INIT(a); - LA_NUMBER(a)=protocol; - LA_TYPE(a)=LA_TYPE_NUMBER; - retv=nss2nslcd(_nss_ldap_getbyname(&a,&result,buffer,1024,&errnop,_nss_ldap_filt_getprotobynumber,LM_PROTOCOLS,_nss_ldap_parse_proto)); - /* write the response */ - WRITE_INT32(fp,retv); - if (retv==NSLCD_RESULT_SUCCESS) - { - NSLCD_PROTOCOL; - } - WRITE_FLUSH(fp); - /* we're done */ - return 0; -} - -int nslcd_protocol_all(FILE *fp) -{ - int32_t tmpint32,tmp2int32,tmp3int32; - static struct ent_context *protocol_context; - /* these are here for now until we rewrite the LDAP code */ - struct protoent result; - char buffer[1024]; - int errnop; - int retv; - /* log call */ - log_log(LOG_DEBUG,"nslcd_protocol_all()"); - /* write the response header */ - WRITE_INT32(fp,NSLCD_VERSION); - WRITE_INT32(fp,NSLCD_ACTION_PROTOCOL_ALL); - /* initialize context */ - if (_nss_ldap_ent_context_init(&protocol_context)==NULL) - return -1; - /* loop over all results */ - while ((retv=nss2nslcd(_nss_ldap_getent(&protocol_context,&result,buffer,1024,&errnop,_nss_ldap_filt_getprotoent,LM_PROTOCOLS,_nss_ldap_parse_proto)))==NSLCD_RESULT_SUCCESS) - { - /* write the result code */ - WRITE_INT32(fp,retv); - /* write the entry */ - NSLCD_PROTOCOL; - } - /* write the final result code */ - WRITE_INT32(fp,retv); - WRITE_FLUSH(fp); - /* FIXME: if a previous call returns what happens to the context? */ - _nss_ldap_enter(); - _nss_ldap_ent_context_release(protocol_context); - _nss_ldap_leave(); - /* we're done */ - return 0; -} diff --git a/server/resolve.c b/server/resolve.c deleted file mode 100644 index 470d33d..0000000 --- a/server/resolve.c +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Hvgskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the Kungliga Tekniska - * Hvgskolan and its contributors. - * - * 4. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <sys/types.h> -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <string.h> -#ifdef HAVE_STRINGS_H -#include <strings.h> -#endif -#include <resolv.h> - -#include "resolve.h" - -#if defined(HAVE_RES_SEARCH) && defined(HAVE_DN_EXPAND) - -#define DECL(X) {#X, T_##X} - -static struct stot -{ - char *name; - int type; -} -stot[] = -{ - DECL (A), - DECL (NS), - DECL (CNAME), DECL (PTR), DECL (MX), DECL (TXT), DECL (AFSDB), DECL (SRV), - { - NULL, 0} -}; - -static int -string_to_type (const char *name) -{ - struct stot *p = stot; - for (p = stot; p->name; p++) - if (strcasecmp (name, p->name) == 0) - return p->type; - return -1; -} - -void -dns_free_data (struct dns_reply *r) -{ - struct resource_record *rr; - if (r->q.domain) - free (r->q.domain); - for (rr = r->head; rr;) - { - struct resource_record *tmp = rr; - if (rr->domain) - free (rr->domain); - if (rr->u.data) - free (rr->u.data); - rr = rr->next; - free (tmp); - } - free (r); -} - -static struct dns_reply * -parse_reply (unsigned char *data, int len) -{ - unsigned char *p; - char host[128]; - int status; - int query, response; - - struct dns_reply *r; - struct resource_record **rr; - - r = (struct dns_reply *) malloc (sizeof (struct dns_reply)); - memset (r, 0, sizeof (struct dns_reply)); - r->q.domain = NULL; - - p = data; - memcpy (&r->h, p, sizeof (HEADER)); - p += sizeof (HEADER); - for (query = 0; query < ntohs(r->h.qdcount); query++) - { - status = dn_expand (data, data + len, p, host, sizeof (host)); - if (status < 0) - { - dns_free_data (r); - return NULL; - } - p += status; - if (p + 4 > data + len) - { - dns_free_data (r); - return NULL; - } - if (r->q.domain == NULL) - { - r->q.domain = strdup (host); - r->q.type = (p[0] << 8 | p[1]); - r->q.class = (p[2] << 8 | p[3]); - } - p += 4; - } - rr = &r->head; - for (response = 0; (response < ntohs(r->h.ancount)) && (p < data + len); response++) - { - unsigned int type, class, ttl, size; - status = dn_expand (data, data + len, p, host, sizeof (host)); - if (status < 0) - { - dns_free_data (r); - return NULL; - } - p += status; - if (p + 10 > data + len) - { - dns_free_data (r); - return NULL; - } - type = (p[0] << 8) | p[1]; - p += 2; - class = (p[0] << 8) | p[1]; - p += 2; - ttl = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; - p += 4; - size = (p[0] << 8) | p[1]; - p += 2; - if (p + size > data + len) - { - dns_free_data (r); - return NULL; - } - *rr = (struct resource_record *) calloc (1, - sizeof (struct - resource_record)); - (*rr)->domain = strdup (host); - (*rr)->type = type; - (*rr)->class = class; - (*rr)->ttl = ttl; - (*rr)->size = size; - switch (type) - { - case T_NS: - case T_CNAME: - case T_PTR: - status = dn_expand (data, data + len, p, host, sizeof (host)); - if (status < 0) - { - dns_free_data (r); - return NULL; - } - (*rr)->u.txt = strdup (host); - break; - case T_MX: - case T_AFSDB: - { - if (p + 2 > data + len) - { - dns_free_data (r); - return NULL; - } - status = dn_expand (data, data + len, p + 2, host, sizeof (host)); - if (status < 0) - { - dns_free_data (r); - return NULL; - } - - (*rr)->u.mx = - (struct mx_record *) malloc (sizeof (struct mx_record) + - strlen (host)); - (*rr)->u.mx->preference = (p[0] << 8) | p[1]; - strcpy ((*rr)->u.mx->domain, host); - break; - } - case T_SRV: - { - if (p + 6 > data + len) - { - dns_free_data (r); - return NULL; - } - status = dn_expand (data, data + len, p + 6, host, sizeof (host)); - if (status < 0) - { - dns_free_data (r); - return NULL; - } - (*rr)->u.srv = - (struct srv_record *) malloc (sizeof (struct srv_record) + - strlen (host)); - (*rr)->u.srv->priority = (p[0] << 8) | p[1]; - (*rr)->u.srv->weight = (p[2] << 8) | p[3]; - (*rr)->u.srv->port = (p[4] << 8) | p[5]; - strcpy ((*rr)->u.srv->target, host); - break; - } - case T_TXT: - { - if (p + *p > data + len) - { - dns_free_data (r); - return NULL; - } - (*rr)->u.txt = (char *) malloc (size + 1); - strncpy ((*rr)->u.txt, (char *) p + 1, *p); - (*rr)->u.txt[*p] = 0; - break; - } - - default: - (*rr)->u.data = (unsigned char *) malloc (size); - memcpy ((*rr)->u.data, p, size); - } - p += size; - rr = &(*rr)->next; - } - *rr = NULL; - return r; -} - -struct dns_reply * -dns_lookup (const char *domain, const char *type_name) -{ - unsigned char *reply = NULL; - int len, rlen; - int type; - struct dns_reply *r = NULL; - - type = string_to_type (type_name); - rlen = 1024; - reply = malloc(rlen); - do - { - len = res_search (domain, C_IN, type, reply, rlen); - if ((len == -1) || (len < rlen)) - { - break; - } - reply = realloc (reply, len + 1024); - rlen = len + 1024; - } - while (1); - if (len >= 0) - r = parse_reply (reply, len); - free(reply); - return r; -} - -#else /* defined(HAVE_RES_SEARCH) && defined(HAVE_DN_EXPAND) */ - -struct dns_reply * -dns_lookup (const char *domain, const char *type_name) -{ - return NULL; -} - -void -dns_free_data (struct dns_reply *r) -{ -} - -#endif /* not ( defined(HAVE_RES_SEARCH) && defined(HAVE_DN_EXPAND) ) */ - -#ifdef TEST - -int -main (int argc, char **argv) -{ - struct dns_reply *r; - struct resource_record *rr; - r = dns_lookup (argv[1], argv[2]); - if (r == NULL) - { - printf ("No reply.\n"); - return 1; - } - for (rr = r->head; rr; rr = rr->next) - { - printf ("%s %s %d ", rr->domain, type_to_string (rr->type), rr->ttl); - switch (rr->type) - { - case T_NS: - printf ("%s\n", (char *) rr->data); - break; - case T_A: - printf ("%d.%d.%d.%d\n", - ((unsigned char *) rr->data)[0], - ((unsigned char *) rr->data)[1], - ((unsigned char *) rr->data)[2], - ((unsigned char *) rr->data)[3]); - break; - case T_MX: - case T_AFSDB: - { - struct mx_record *mx = (struct mx_record *) rr->data; - printf ("%d %s\n", mx->preference, mx->domain); - break; - } - case T_SRV: - { - struct srv_record *srv = (struct srv_record *) rr->data; - printf ("%d %d %d %s\n", srv->priority, srv->weight, - srv->port, srv->target); - break; - } - default: - printf ("\n"); - break; - } - } - - return 0; -} -#endif /* TEST */ diff --git a/server/resolve.h b/server/resolve.h deleted file mode 100644 index 62b2574..0000000 --- a/server/resolve.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Hvgskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the Kungliga Tekniska - * Hvgskolan and its contributors. - * - * 4. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* THIS IS NOT (yet) A PUBLIC INTERFACE */ - -#ifndef __RESOLVE_H__ -#define __RESOLVE_H__ - -/* when would this *not* be defined? */ -#define HAVE_ARPA_NAMESER_H - -/* We use these, but they are not always present in <arpa/nameser.h> */ - -#ifndef T_TXT -#define T_TXT 16 -#endif -#ifndef T_AFSDB -#define T_AFSDB 18 -#endif -#ifndef T_SRV -#define T_SRV 33 -#endif - -struct dns_query -{ - char *domain; - unsigned type; - unsigned class; -}; - -struct mx_record -{ - unsigned preference; - char domain[1]; -}; - -struct srv_record -{ - unsigned priority; - unsigned weight; - unsigned port; - char target[1]; -}; - -struct resource_record -{ - char *domain; - unsigned type; - unsigned class; - unsigned ttl; - unsigned size; - union - { - void *data; - struct mx_record *mx; - struct mx_record *afsdb; /* mx and afsdb are identical */ - struct srv_record *srv; - struct in_addr *a; - char *txt; - } - u; - struct resource_record *next; -}; - -#ifndef HAVE_ARPA_NAMESER_H /* XXX */ -typedef int HEADER; /* will never be used */ -#endif - -struct dns_reply -{ - HEADER h; - struct dns_query q; - struct resource_record *head; -}; - -#define dns_lookup _nss_ldap_dns_lookup -#define dns_free_data _nss_ldap_dns_free_data - -struct dns_reply *dns_lookup (const char *, const char *); - -void dns_free_data (struct dns_reply *r); - -#endif /* __RESOLVE_H__ */ diff --git a/server/rpc.c b/server/rpc.c deleted file mode 100644 index b58cca7..0000000 --- a/server/rpc.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - rpc.c - rpc name lookup routines - This file was part of the nss_ldap library (as ldap-rpc.c) which - has been forked into the nss-ldapd library. - - Copyright (C) 1997-2005 Luke Howard - Copyright (C) 2006 West Consulting - Copyright (C) 2006 Arthur de Jong - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1301 USA -*/ - -/* - Determine the canonical name of the RPC with _nss_ldap_getrdnvalue(), - and assign any values of "cn" which do NOT match this canonical name - as aliases. - */ - -#include "config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#ifdef HAVE_RPC_RPCENT_H -#include <rpc/rpcent.h> -#else -#include <netdb.h> -#endif -#ifdef HAVE_LBER_H -#include <lber.h> -#endif -#ifdef HAVE_LDAP_H -#include <ldap.h> -#endif -#if defined(HAVE_THREAD_H) -#include <thread.h> -#elif defined(HAVE_PTHREAD_H) -#include <pthread.h> -#endif - -#include "ldap-nss.h" -#include "util.h" -#include "common.h" -#include "log.h" - -/* macros for expanding the NSLCD_RPC macro */ -#define NSLCD_STRING(field) WRITE_STRING(fp,field) -#define NSLCD_STRINGLIST(field) WRITE_STRINGLIST_NULLTERM(fp,field) -#define NSLCD_INT32(field) WRITE_INT32(fp,field) -#define RPC_NAME result->r_name -#define RPC_ALIASES result->r_aliases -#define RPC_NUMBER result->r_number - -/* write a single rpc entry to the stream */ -static int write_rpcent(FILE *fp,struct rpcent *result) -{ - int32_t tmpint32,tmp2int32,tmp3int32; - NSLCD_RPC; - return 0; -} - -static enum nss_status _nss_ldap_parse_rpc (LDAPMessage * e, - struct ldap_state * pvt, - void *result, char *buffer, size_t buflen) -{ - - struct rpcent *rpc = (struct rpcent *) result; - char *number; - enum nss_status stat; - - stat = - _nss_ldap_getrdnvalue (e, ATM (LM_RPC, cn), &rpc->r_name, &buffer, - &buflen); - if (stat != NSS_STATUS_SUCCESS) - return stat; - - stat = - _nss_ldap_assign_attrval (e, AT (oncRpcNumber), &number, &buffer, - &buflen); - if (stat != NSS_STATUS_SUCCESS) - return stat; - - rpc->r_number = atol (number); - - stat = - _nss_ldap_assign_attrvals (e, ATM (LM_RPC, cn), rpc->r_name, - &rpc->r_aliases, &buffer, &buflen, NULL); - if (stat != NSS_STATUS_SUCCESS) - return stat; - - return NSS_STATUS_SUCCESS; -} - -int nslcd_rpc_byname(FILE *fp) -{ - int32_t tmpint32; - char *name; - struct ldap_args a; - /* these are here for now until we rewrite the LDAP code */ - struct rpcent result; - char buffer[1024]; - int errnop; - int retv; - /* read request parameters */ - READ_STRING_ALLOC(fp,name); - /* log call */ - log_log(LOG_DEBUG,"nslcd_rpc_byname(%s)",name); - /* write the response header */ - WRITE_INT32(fp,NSLCD_VERSION); - WRITE_INT32(fp,NSLCD_ACTION_RPC_BYNAME); - /* do the LDAP request */ - LA_INIT(a); - LA_STRING(a)=name; - LA_TYPE(a)=LA_TYPE_STRING; - retv=nss2nslcd(_nss_ldap_getbyname(&a,&result,buffer,1024,&errnop,_nss_ldap_filt_getrpcbyname,LM_RPC,_nss_ldap_parse_rpc)); - /* no more need for this string */ - free(name); - /* write the response */ - WRITE_INT32(fp,retv); - if (retv==NSLCD_RESULT_SUCCESS) - write_rpcent(fp,&result); - WRITE_FLUSH(fp); - /* we're done */ - return 0; -} - -int nslcd_rpc_bynumber(FILE *fp) -{ - int32_t tmpint32; - int number; - struct ldap_args a; - /* these are here for now until we rewrite the LDAP code */ - struct rpcent result; - char buffer[1024]; - int errnop; - int retv; - /* read request parameters */ - READ_INT32(fp,number); - /* log call */ - log_log(LOG_DEBUG,"nslcd_rpc_bynumber(%d)",number); - /* write the response header */ - WRITE_INT32(fp,NSLCD_VERSION); - WRITE_INT32(fp,NSLCD_ACTION_RPC_BYNUMBER); - /* do the LDAP request */ - LA_INIT(a); - LA_NUMBER(a)=number; - LA_TYPE(a)=LA_TYPE_NUMBER; - retv=nss2nslcd(_nss_ldap_getbyname(&a,&result,buffer,1024,&errnop,_nss_ldap_filt_getrpcbynumber,LM_RPC,_nss_ldap_parse_rpc)); - /* write the response */ - WRITE_INT32(fp,retv); - if (retv==NSLCD_RESULT_SUCCESS) - write_rpcent(fp,&result); - WRITE_FLUSH(fp); - /* we're done */ - return 0; -} - -int nslcd_rpc_all(FILE *fp) -{ - int32_t tmpint32; - static struct ent_context *rpc_context; - /* these are here for now until we rewrite the LDAP code */ - struct rpcent result; - char buffer[1024]; - int errnop; - int retv; - /* log call */ - log_log(LOG_DEBUG,"nslcd_rpc_all()"); - /* write the response header */ - WRITE_INT32(fp,NSLCD_VERSION); - WRITE_INT32(fp,NSLCD_ACTION_RPC_ALL); - /* initialize context */ - if (_nss_ldap_ent_context_init(&rpc_context)==NULL) - return -1; - /* loop over all results */ - while ((retv=nss2nslcd(_nss_ldap_getent(&rpc_context,&result,buffer,1024,&errnop,_nss_ldap_filt_getrpcent,LM_RPC,_nss_ldap_parse_rpc)))==NSLCD_RESULT_SUCCESS) - { - /* write the result code */ - WRITE_INT32(fp,retv); - /* write the entry */ - write_rpcent(fp,&result); - } - /* write the final result code */ - WRITE_INT32(fp,retv); - WRITE_FLUSH(fp); - /* FIXME: if a previous call returns what happens to the context? */ - _nss_ldap_enter(); - _nss_ldap_ent_context_release(rpc_context); - _nss_ldap_leave(); - /* we're done */ - return 0; -} diff --git a/server/service.c b/server/service.c deleted file mode 100644 index 7739b8e..0000000 --- a/server/service.c +++ /dev/null @@ -1,302 +0,0 @@ -/* - service.c - service entry lookup routines - This file was part of the nss_ldap library (as ldap-service.c) - which has been forked into the nss-ldapd library. - - Copyright (C) 1997-2005 Luke Howard - Copyright (C) 2006 West Consulting - Copyright (C) 2006 Arthur de Jong - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1301 USA -*/ - -/* - Determine the canonical name of the RPC with _nss_ldap_getrdnvalue(), - and assign any values of "cn" which do NOT match this canonical name - as aliases. - */ - -#include "config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <netdb.h> -#include <netinet/in.h> -#include <errno.h> -#ifdef HAVE_SYS_BYTEORDER_H -#include <sys/byteorder.h> -#endif -#ifdef HAVE_LBER_H -#include <lber.h> -#endif -#ifdef HAVE_LDAP_H -#include <ldap.h> -#endif -#if defined(HAVE_THREAD_H) -#include <thread.h> -#elif defined(HAVE_PTHREAD_H) -#include <pthread.h> -#endif - -#include "ldap-nss.h" -#include "util.h" -#include "common.h" -#include "log.h" - -/* macros for expanding the NSLCD_SERVICE macro */ -#define NSLCD_STRING(field) WRITE_STRING(fp,field) -#define NSLCD_STRINGLIST(field) WRITE_STRINGLIST_NULLTERM(fp,field) -#define NSLCD_INT32(field) WRITE_INT32(fp,field) -#define SERVICE_NAME result->s_name -#define SERVICE_ALIASES result->s_aliases -#define SERVICE_NUMBER htons(result->s_port) -#define SERVICE_PROTOCOL result->s_proto - -/* write a single host entry to the stream */ -static int write_servent(FILE *fp,struct servent *result) -{ - int32_t tmpint32,tmp2int32,tmp3int32; - NSLCD_SERVICE; - return 0; -} - -static enum nss_status _nss_ldap_parse_serv (LDAPMessage *e, - struct ldap_state *state, - void *result,char *buffer,size_t buflen) -{ - struct servent *service = (struct servent *)result; - char *port; - enum nss_status stat = NSS_STATUS_SUCCESS; - - /* this is complicated and ugly, because some git (me) specified that service - * entries should expand to two entities (or more) if they have multi-valued - * ipServiceProtocol fields. - */ - - if (state->ls_type == LS_TYPE_KEY) - { - if (state->ls_info.ls_key == NULL) - { - /* non-deterministic behaviour is ok */ - stat = - _nss_ldap_assign_attrval (e, AT (ipServiceProtocol), - &service->s_proto, &buffer, &buflen); - if (stat != NSS_STATUS_SUCCESS) - { - return stat; - } - } - else - { - register int len; - len = strlen (state->ls_info.ls_key); - if (buflen < (size_t) (len + 1)) - { - return NSS_STATUS_TRYAGAIN; - } - strncpy (buffer, state->ls_info.ls_key, len); - buffer[len] = '\0'; - service->s_proto = buffer; - buffer += len + 1; - buflen -= len + 1; - } - } - else - { - char **vals = _nss_ldap_get_values (e, AT (ipServiceProtocol)); - int len; - if (vals == NULL) - { - state->ls_info.ls_index = -1; - return NSS_STATUS_NOTFOUND; - } - - switch (state->ls_info.ls_index) - { - case 0: - /* last time. decrementing ls_index to -1 AND returning !NSS_STATUS_SUCCESS - will force this entry to be discarded. - */ - stat = NSS_STATUS_NOTFOUND; - break; - case -1: - /* first time */ - state->ls_info.ls_index = ldap_count_values (vals); - /* fall off to default ... */ - default: - len = strlen (vals[state->ls_info.ls_index - 1]); - if (buflen < (size_t) (len + 1)) - { - return NSS_STATUS_TRYAGAIN; - } - strncpy (buffer, vals[state->ls_info.ls_index - 1], len); - buffer[len] = '\0'; - service->s_proto = buffer; - buffer += len + 1; - buflen -= len + 1; - stat = NSS_STATUS_SUCCESS; - } - - ldap_value_free (vals); - state->ls_info.ls_index--; - } - - if (stat != NSS_STATUS_SUCCESS) - { - return stat; - } - - stat = - _nss_ldap_getrdnvalue (e, ATM (LM_SERVICES, cn), &service->s_name, - &buffer, &buflen); - if (stat != NSS_STATUS_SUCCESS) - { - return stat; - } - - stat = - _nss_ldap_assign_attrvals (e, ATM (LM_SERVICES, cn), service->s_name, - &service->s_aliases, &buffer, &buflen, NULL); - if (stat != NSS_STATUS_SUCCESS) - { - return stat; - } - - stat = - _nss_ldap_assign_attrval (e, AT (ipServicePort), &port, &buffer, - &buflen); - if (stat != NSS_STATUS_SUCCESS) - { - return stat; - } - - service->s_port = htons (atoi (port)); - - return NSS_STATUS_SUCCESS; -} - -int nslcd_service_byname(FILE *fp) -{ - int32_t tmpint32; - char *name,*protocol; - struct ldap_args a; - /* these are here for now until we rewrite the LDAP code */ - struct servent result; - char buffer[1024]; - int errnop; - int retv; - /* read request parameters */ - READ_STRING_ALLOC(fp,name); - READ_STRING_ALLOC(fp,protocol); - /* log call */ - log_log(LOG_DEBUG,"nslcd_service_byname(%s,%s)",name,protocol); - /* write the response header */ - WRITE_INT32(fp,NSLCD_VERSION); - WRITE_INT32(fp,NSLCD_ACTION_SERVICE_BYNAME); - /* do the LDAP request */ - LA_INIT(a); - LA_STRING(a)=name; - LA_TYPE(a)=(strlen(protocol)==0)?LA_TYPE_STRING:LA_TYPE_STRING_AND_STRING; - LA_STRING2(a)=protocol; - retv=nss2nslcd(_nss_ldap_getbyname(&a,&result,buffer,1024,&errnop, - ((strlen(protocol)==0)?_nss_ldap_filt_getservbyname:_nss_ldap_filt_getservbynameproto), - LM_SERVICES,_nss_ldap_parse_serv)); - /* no more need for these strings */ - free(name); - free(protocol); - /* write the response */ - WRITE_INT32(fp,retv); - if (retv==NSLCD_RESULT_SUCCESS) - write_servent(fp,&result); - WRITE_FLUSH(fp); - /* we're done */ - return 0; -} - -int nslcd_service_bynumber(FILE *fp) -{ - int32_t tmpint32; - int number; - char *protocol; - struct ldap_args a; - /* these are here for now until we rewrite the LDAP code */ - struct servent result; - char buffer[1024]; - int errnop; - int retv; - /* read request parameters */ - READ_INT32(fp,number); - READ_STRING_ALLOC(fp,protocol); - /* log call */ - log_log(LOG_DEBUG,"nslcd_service_bynumber(%d,%s)",number,protocol); - /* write the response header */ - WRITE_INT32(fp,NSLCD_VERSION); - WRITE_INT32(fp,NSLCD_ACTION_SERVICE_BYNUMBER); - /* do the LDAP request */ - LA_INIT(a); - LA_NUMBER(a)=number; - LA_TYPE(a)=(strlen(protocol)==0)?LA_TYPE_NUMBER:LA_TYPE_NUMBER_AND_STRING; - LA_STRING2(a)=protocol; - retv=nss2nslcd(_nss_ldap_getbyname(&a,&result,buffer,1024,&errnop, - ((strlen(protocol)==0)?_nss_ldap_filt_getservbyport:_nss_ldap_filt_getservbyportproto), - LM_SERVICES,_nss_ldap_parse_serv)); - /* no more need for this string */ - free(protocol); - /* write the response */ - WRITE_INT32(fp,retv); - if (retv==NSLCD_RESULT_SUCCESS) - write_servent(fp,&result); - WRITE_FLUSH(fp); - /* we're done */ - return 0; -} - -int nslcd_service_all(FILE *fp) -{ - int32_t tmpint32; - static struct ent_context *serv_context; - /* these are here for now until we rewrite the LDAP code */ - struct servent result; - char buffer[1024]; - int errnop; - int retv; - /* log call */ - log_log(LOG_DEBUG,"nslcd_service_all()"); - /* write the response header */ - WRITE_INT32(fp,NSLCD_VERSION); - WRITE_INT32(fp,NSLCD_ACTION_SERVICE_ALL); - /* initialize context */ - if (_nss_ldap_ent_context_init(&serv_context)==NULL) - return -1; - /* loop over all results */ - while ((retv=nss2nslcd(_nss_ldap_getent(&serv_context,&result,buffer,1024,&errnop,_nss_ldap_filt_getservent,LM_SERVICES,_nss_ldap_parse_serv)))==NSLCD_RESULT_SUCCESS) - { - /* write the result code */ - WRITE_INT32(fp,retv); - /* write the entry */ - write_servent(fp,&result); - } - /* write the final result code */ - WRITE_INT32(fp,retv); - WRITE_FLUSH(fp); - /* FIXME: if a previous call returns what happens to the context? */ - _nss_ldap_enter(); - _nss_ldap_ent_context_release(serv_context); - _nss_ldap_leave(); - /* we're done */ - return 0; -} diff --git a/server/shadow.c b/server/shadow.c deleted file mode 100644 index d1b22bd..0000000 --- a/server/shadow.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - shadow.c - service entry lookup routines - This file was part of the nss_ldap library (as ldap-spwd.c) which - has been forked into the nss-ldapd library. - - Copyright (C) 1997-2005 Luke Howard - Copyright (C) 2006 West Consulting - Copyright (C) 2006 Arthur de Jong - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1301 USA -*/ - -#include "config.h" - -#include <stdlib.h> -#include <string.h> -#include <shadow.h> -#include <errno.h> -#ifdef HAVE_PROT_H -#define _PROT_INCLUDED -#endif -#ifdef HAVE_LBER_H -#include <lber.h> -#endif -#ifdef HAVE_LDAP_H -#include <ldap.h> -#endif -#if defined(HAVE_THREAD_H) -#include <thread.h> -#elif defined(HAVE_PTHREAD_H) -#include <pthread.h> -#endif - -#include "ldap-nss.h" -#include "util.h" -#include "common.h" -#include "log.h" - -static enum nss_status _nss_ldap_parse_sp(LDAPMessage *e, - struct ldap_state *pvt, - void *result,char *buffer,size_t buflen) -{ - struct spwd *sp = (struct spwd *) result; - enum nss_status stat; - char *tmp = NULL; - - stat = - _nss_ldap_assign_userpassword (e, ATM (LM_SHADOW, userPassword), - &sp->sp_pwdp, &buffer, &buflen); - if (stat != NSS_STATUS_SUCCESS) - return stat; - - stat = - _nss_ldap_assign_attrval (e, ATM (LM_SHADOW, uid), &sp->sp_namp, &buffer, - &buflen); - if (stat != NSS_STATUS_SUCCESS) - return stat; - - stat = - _nss_ldap_assign_attrval (e, AT (shadowLastChange), &tmp, &buffer, - &buflen); - sp->sp_lstchg = (stat == NSS_STATUS_SUCCESS) ? _nss_ldap_shadow_date (tmp) : -1; - - stat = - _nss_ldap_assign_attrval (e, AT (shadowMax), &tmp, &buffer, &buflen); - sp->sp_max = (stat == NSS_STATUS_SUCCESS) ? atol (tmp) : -1; - - stat = - _nss_ldap_assign_attrval (e, AT (shadowMin), &tmp, &buffer, &buflen); - sp->sp_min = (stat == NSS_STATUS_SUCCESS) ? atol (tmp) : -1; - - stat = - _nss_ldap_assign_attrval (e, AT (shadowWarning), &tmp, &buffer, - &buflen); - sp->sp_warn = (stat == NSS_STATUS_SUCCESS) ? atol (tmp) : -1; - - stat = - _nss_ldap_assign_attrval (e, AT (shadowInactive), &tmp, &buffer, - &buflen); - sp->sp_inact = (stat == NSS_STATUS_SUCCESS) ? atol (tmp) : -1; - - stat = - _nss_ldap_assign_attrval (e, AT (shadowExpire), &tmp, &buffer, - &buflen); - sp->sp_expire = (stat == NSS_STATUS_SUCCESS) ? _nss_ldap_shadow_date (tmp) : -1; - - stat = - _nss_ldap_assign_attrval (e, AT (shadowFlag), &tmp, &buffer, &buflen); - sp->sp_flag = (stat == NSS_STATUS_SUCCESS) ? atol (tmp) : 0; - - _nss_ldap_shadow_handle_flag(sp); - - return NSS_STATUS_SUCCESS; -} - -/* macros for expanding the NSLCD_SHADOW macro */ -#define NSLCD_STRING(field) WRITE_STRING(fp,field) -#define NSLCD_INT32(field) WRITE_INT32(fp,field) -#define SHADOW_NAME result.sp_namp -#define SHADOW_PASSWD result.sp_pwdp -#define SHADOW_LASTCHANGE result.sp_lstchg -#define SHADOW_MINDAYS result.sp_min -#define SHADOW_MAXDAYS result.sp_max -#define SHADOW_WARN result.sp_warn -#define SHADOW_INACT result.sp_inact -#define SHADOW_EXPIRE result.sp_expire -#define SHADOW_FLAG result.sp_flag - -int nslcd_shadow_byname(FILE *fp) -{ - int32_t tmpint32; - char *name; - struct ldap_args a; - int retv; - struct spwd result; - char buffer[1024]; - int errnop; - /* read request parameters */ - READ_STRING_ALLOC(fp,name); - /* log call */ - log_log(LOG_DEBUG,"nslcd_shadow_byname(%s)",name); - /* write the response header */ - WRITE_INT32(fp,NSLCD_VERSION); - WRITE_INT32(fp,NSLCD_ACTION_SHADOW_BYNAME); - /* do the LDAP request */ - LA_INIT(a); - LA_STRING(a)=name; - LA_TYPE(a)=LA_TYPE_STRING; - retv=nss2nslcd(_nss_ldap_getbyname(&a,&result,buffer,1024,&errnop,_nss_ldap_filt_getspnam,LM_SHADOW,_nss_ldap_parse_sp)); - /* no more need for this string */ - free(name); - /* write the response */ - WRITE_INT32(fp,retv); - if (retv==NSLCD_RESULT_SUCCESS) - { - NSLCD_SHADOW; - } - WRITE_FLUSH(fp); - /* we're done */ - return 0; -} - -int nslcd_shadow_all(FILE *fp) -{ - int32_t tmpint32; - static struct ent_context *shadow_context; - /* these are here for now until we rewrite the LDAP code */ - struct spwd result; - char buffer[1024]; - int errnop; - int retv; - /* log call */ - log_log(LOG_DEBUG,"nslcd_shadow_all()"); - /* write the response header */ - WRITE_INT32(fp,NSLCD_VERSION); - WRITE_INT32(fp,NSLCD_ACTION_SHADOW_ALL); - /* initialize context */ - if (_nss_ldap_ent_context_init(&shadow_context)==NULL) - return -1; - /* loop over all results */ - while ((retv=nss2nslcd(_nss_ldap_getent(&shadow_context,&result,buffer,1024,&errnop,_nss_ldap_filt_getspent,LM_SHADOW,_nss_ldap_parse_sp)))==NSLCD_RESULT_SUCCESS) - { - /* write the result */ - WRITE_INT32(fp,retv); - NSLCD_SHADOW; - } - /* write the final result code */ - WRITE_INT32(fp,retv); - WRITE_FLUSH(fp); - /* FIXME: if a previous call returns what happens to the context? */ - _nss_ldap_enter(); - _nss_ldap_ent_context_release(shadow_context); - _nss_ldap_leave(); - /* we're done */ - return 0; -} diff --git a/server/util.c b/server/util.c deleted file mode 100644 index 57d6a10..0000000 --- a/server/util.c +++ /dev/null @@ -1,1669 +0,0 @@ -/* - util.c - LDAP utility functions - This file was part of the nss_ldap library which has been - forked into the nss-ldapd library. - - Copyright (C) 1997-2005 Luke Howard - Copyright (C) 2006 West Consulting - Copyright (C) 2006 Arthur de Jong - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1301 USA -*/ - -#include "config.h" - -#include <stdio.h> -#include <string.h> -#ifdef HAVE_STRINGS_H -#include <strings.h> -#endif -#include <stdlib.h> -#include <sys/param.h> -#include <sys/stat.h> -#include <netdb.h> -#include <syslog.h> -#include <string.h> -#include <fcntl.h> -#include <assert.h> -#ifdef HAVE_LBER_H -#include <lber.h> -#endif -#ifdef HAVE_LDAP_H -#include <ldap.h> -#endif -#if defined(HAVE_THREAD_H) -#include <thread.h> -#elif defined(HAVE_PTHREAD_H) -#include <pthread.h> -#endif - -#include "ldap-nss.h" -#include "util.h" -#include "common.h" -#include "log.h" - - -#define NSS_LDAP_KEY_MAP_ATTRIBUTE "nss_map_attribute" -#define NSS_LDAP_KEY_MAP_OBJECTCLASS "nss_map_objectclass" -#define NSS_LDAP_KEY_SET_OVERRIDE "nss_override_attribute_value" -#define NSS_LDAP_KEY_SET_DEFAULT "nss_default_attribute_value" -#define NSS_LDAP_KEY_HOST "host" -#define NSS_LDAP_KEY_SCOPE "scope" -#define NSS_LDAP_KEY_BASE "base" -#define NSS_LDAP_KEY_PORT "port" -#define NSS_LDAP_KEY_BINDDN "binddn" -#define NSS_LDAP_KEY_BINDPW "bindpw" -#define NSS_LDAP_KEY_USESASL "use_sasl" -#define NSS_LDAP_KEY_SASLID "sasl_auth_id" -#define NSS_LDAP_KEY_DEREF "deref" -#define NSS_LDAP_KEY_ROOTBINDDN "rootbinddn" -#define NSS_LDAP_KEY_ROOTUSESASL "rootuse_sasl" -#define NSS_LDAP_KEY_ROOTSASLID "rootsasl_auth_id" -#define NSS_LDAP_KEY_LDAP_VERSION "ldap_version" -#define NSS_LDAP_KEY_TIMELIMIT "timelimit" -#define NSS_LDAP_KEY_BIND_TIMELIMIT "bind_timelimit" -#define NSS_LDAP_KEY_SSL "ssl" -#define NSS_LDAP_KEY_SSLPATH "sslpath" -#define NSS_LDAP_KEY_REFERRALS "referrals" -#define NSS_LDAP_KEY_RESTART "restart" -#define NSS_LDAP_KEY_URI "uri" -#define NSS_LDAP_KEY_IDLE_TIMELIMIT "idle_timelimit" -#define NSS_LDAP_KEY_RECONNECT_POLICY "bind_policy" -#define NSS_LDAP_KEY_SASL_SECPROPS "sasl_secprops" -#ifdef CONFIGURE_KRB5_CCNAME -#define NSS_LDAP_KEY_KRB5_CCNAME "krb5_ccname" -#endif /* CONFIGURE_KRB5_CCNAME */ -#define NSS_LDAP_KEY_LOGDIR "logdir" -#define NSS_LDAP_KEY_DEBUG "debug" -#define NSS_LDAP_KEY_PAGESIZE "pagesize" -#define NSS_LDAP_KEY_INITGROUPS "nss_initgroups" -#define NSS_LDAP_KEY_INITGROUPS_IGNOREUSERS "nss_initgroups_ignoreusers" - -/* more reconnect policy fine-tuning */ -#define NSS_LDAP_KEY_RECONNECT_TRIES "nss_reconnect_tries" -#define NSS_LDAP_KEY_RECONNECT_SLEEPTIME "nss_reconnect_sleeptime" -#define NSS_LDAP_KEY_RECONNECT_MAXSLEEPTIME "nss_reconnect_maxsleeptime" -#define NSS_LDAP_KEY_RECONNECT_MAXCONNTRIES "nss_reconnect_maxconntries" - -#define NSS_LDAP_KEY_PAGED_RESULTS "nss_paged_results" -#define NSS_LDAP_KEY_SCHEMA "nss_schema" -#define NSS_LDAP_KEY_SRV_DOMAIN "nss_srv_domain" -#define NSS_LDAP_KEY_CONNECT_POLICY "nss_connect_policy" - -/* - * Timeouts for reconnecting code. Similar to rebind - * logic in Darwin NetInfo. Some may find sleeping - * unacceptable, in which case you may wish to adjust - * the constants below. - */ -#define LDAP_NSS_TRIES 5 /* number of sleeping reconnect attempts */ -#define LDAP_NSS_SLEEPTIME 4 /* seconds to sleep; doubled until max */ -#define LDAP_NSS_MAXSLEEPTIME 64 /* maximum seconds to sleep */ -#define LDAP_NSS_MAXCONNTRIES 2 /* reconnect attempts before sleeping */ - -#define LDAP_PAGESIZE 1000 - - -static struct ldap_dictionary *do_alloc_dictionary(void); -static enum nss_status do_getrdnvalue (const char *dn, - const char *rdntype, - char **rval, char **buffer, - size_t * buflen); - -static enum nss_status do_parse_map_statement (struct ldap_config * cfg, - const char *statement, - enum ldap_map_type type); - -static enum nss_status do_searchdescriptorconfig (const char *key, - const char *value, - size_t valueLength, - struct ldap_service_search_descriptor - ** result, char **buffer, - size_t * buflen); - -static void *__cache = NULL; - -NSS_LDAP_DEFINE_LOCK (__cache_lock); - -#define cache_lock() NSS_LDAP_LOCK(__cache_lock) -#define cache_unlock() NSS_LDAP_UNLOCK(__cache_lock) - -static enum nss_status -dn2uid_cache_put (const char *dn, const char *uid) -{ - enum nss_status status; - struct ldap_datum key, val; - - cache_lock (); - - if (__cache == NULL) - { - __cache = (void *)do_alloc_dictionary(); - if (__cache == NULL) - { - cache_unlock (); - return NSS_STATUS_TRYAGAIN; - } - } - - key.data = (void *) dn; - key.size = strlen (dn); - val.data = (void *) uid; - val.size = strlen (uid); - - status = _nss_ldap_db_put (__cache, 0, &key, &val); - - cache_unlock (); - - return status; -} - -static enum nss_status -dn2uid_cache_get (const char *dn, char **uid, char **buffer, size_t * buflen) -{ - struct ldap_datum key, val; - enum nss_status status; - - cache_lock (); - - if (__cache == NULL) - { - cache_unlock (); - return NSS_STATUS_NOTFOUND; - } - - key.data = (void *) dn; - key.size = strlen (dn); - - status = _nss_ldap_db_get (__cache, 0, &key, &val); - if (status != NSS_STATUS_SUCCESS) - { - cache_unlock (); - return status; - } - - if (*buflen <= val.size) - { - cache_unlock (); - return NSS_STATUS_TRYAGAIN; - } - - *uid = *buffer; - memcpy (*uid, (char *) val.data, val.size); - (*uid)[val.size] = '\0'; - *buffer += val.size + 1; - *buflen -= val.size + 1; - - cache_unlock (); - return NSS_STATUS_SUCCESS; -} - -enum nss_status -_nss_ldap_dn2uid (const char *dn, char **uid, char **buffer, size_t * buflen, - int *pIsNestedGroup, LDAPMessage ** pRes) -{ - enum nss_status status; - - debug ("==> _nss_ldap_dn2uid"); - - *pIsNestedGroup = 0; - - status = dn2uid_cache_get (dn, uid, buffer, buflen); - if (status == NSS_STATUS_NOTFOUND) - { - const char *attrs[4]; - LDAPMessage *res; - - attrs[0] = ATM (LM_PASSWD, uid); - attrs[1] = ATM (LM_GROUP, uniqueMember); - attrs[2] = AT (objectClass); - attrs[3] = NULL; - - if (_nss_ldap_read (dn, attrs, &res) == NSS_STATUS_SUCCESS) - { - LDAPMessage *e = _nss_ldap_first_entry (res); - if (e != NULL) - { - if (_nss_ldap_oc_check (e, OC (posixGroup)) == NSS_STATUS_SUCCESS) - { - *pIsNestedGroup = 1; - *pRes = res; - debug ("<== _nss_ldap_dn2uid (nested group)"); - return NSS_STATUS_SUCCESS; - } - - status = - _nss_ldap_assign_attrval (e, ATM (LM_PASSWD, uid), uid, - buffer, buflen); - if (status == NSS_STATUS_SUCCESS) - dn2uid_cache_put (dn, *uid); - } - } - ldap_msgfree (res); - } - - debug ("<== _nss_ldap_dn2uid"); - - return status; -} - -enum nss_status -_nss_ldap_getrdnvalue (LDAPMessage * entry, - const char *rdntype, - char **rval, char **buffer, size_t * buflen) -{ - char *dn; - enum nss_status status; - - dn = _nss_ldap_get_dn (entry); - if (dn == NULL) - { - return NSS_STATUS_NOTFOUND; - } - - status = do_getrdnvalue (dn, rdntype, rval, buffer, buflen); -#ifdef HAVE_LDAP_MEMFREE - ldap_memfree (dn); -#else /* HAVE_LDAP_MEMFREE */ - free (dn); -#endif /* not HAVE_LDAP_MEMFREE */ - - /* - * If examining the DN failed, then pick the nominal first - * value of cn as the canonical name (recall that attributes - * are sets, not sequences) - */ - if (status == NSS_STATUS_NOTFOUND) - { - char **vals; - - vals = _nss_ldap_get_values (entry, rdntype); - - if (vals != NULL) - { - int rdnlen = strlen (*vals); - if (*buflen > rdnlen) - { - char *rdnvalue = *buffer; - strncpy (rdnvalue, *vals, rdnlen); - rdnvalue[rdnlen] = '\0'; - *buffer += rdnlen + 1; - *buflen -= rdnlen + 1; - *rval = rdnvalue; - status = NSS_STATUS_SUCCESS; - } - else - { - status = NSS_STATUS_TRYAGAIN; - } - ldap_value_free (vals); - } - } - - return status; -} - -int _nss_ldap_write_rndvalue(FILE *fp,LDAPMessage *entry,const char *rdntype) -{ - char *dn; - int status=456; - char **vals; - int32_t tmpint32; - char **exploded_dn; - char **exploded_rdn; - char rdnava[64]; - int rdnavalen; - int i; - /* log call */ - log_log(LOG_DEBUG,"_nss_ldap_write_rndvalue(%s)",rdntype); - /* get the dn from the entry */ - dn=_nss_ldap_get_dn(entry); - if (dn==NULL) - return NSLCD_RESULT_NOTFOUND; - /* append a `=' to the rdntype */ - snprintf(rdnava,sizeof(rdnava),"%s=",rdntype); - rdnavalen=strlen(rdnava); - /* explode dn */ - exploded_dn=ldap_explode_dn(dn,0); - if (exploded_dn!=NULL) - { - /* - * attempt to get the naming attribute's principal - * value by parsing the RDN. We need to support - * multivalued RDNs (as they're essentially mandated - * for services) - */ - exploded_rdn=ldap_explode_rdn(exploded_dn[0],0); - if (exploded_rdn!=NULL) - { - for (i=0;exploded_rdn[i]!=NULL;i++) - { - /* if the values begins with rndava */ - if (strncasecmp(exploded_rdn[i],rdnava,rdnavalen)==0) - { - /* FIXME: handle case where WRITE fails */ - WRITE_STRING(fp,exploded_rdn[i]+rdnavalen); - status=0; - break; - } - } - ldap_value_free(exploded_rdn); - } - ldap_value_free(exploded_dn); - } - ldap_memfree(dn); - /* - * If examining the DN failed, then pick the nominal first - * value of cn as the canonical name (recall that attributes - * are sets, not sequences) - */ - if (status==456) - { - vals=_nss_ldap_get_values(entry,rdntype); - if (vals!=NULL) - { - /* write the first entry */ - WRITE_STRING(fp,vals[0]); - status=NSS_STATUS_SUCCESS; - ldap_value_free(vals); - status=0; - } - } - return status; -} - -static enum nss_status -do_getrdnvalue (const char *dn, - const char *rdntype, - char **rval, char **buffer, size_t * buflen) -{ - char **exploded_dn; - char *rdnvalue = NULL; - char rdnava[64]; - int rdnlen = 0, rdnavalen; - - snprintf (rdnava, sizeof rdnava, "%s=", rdntype); - rdnavalen = strlen (rdnava); - - exploded_dn = ldap_explode_dn (dn, 0); - - if (exploded_dn != NULL) - { - /* - * attempt to get the naming attribute's principal - * value by parsing the RDN. We need to support - * multivalued RDNs (as they're essentially mandated - * for services) - */ -#ifdef HAVE_LDAP_EXPLODE_RDN - /* - * use ldap_explode_rdn() API, as it's cleaner than - * strtok(). This code has not been tested! - */ - char **p, **exploded_rdn; - - exploded_rdn = ldap_explode_rdn (*exploded_dn, 0); - if (exploded_rdn != NULL) - { - for (p = exploded_rdn; *p != NULL; p++) - { - if (strncasecmp (*p, rdnava, rdnavalen) == 0) - { - char *r = *p + rdnavalen; - - rdnlen = strlen (r); - if (*buflen <= rdnlen) - { - ldap_value_free (exploded_rdn); - ldap_value_free (exploded_dn); - return NSS_STATUS_TRYAGAIN; - } - rdnvalue = *buffer; - strncpy (rdnvalue, r, rdnlen); - break; - } - } - ldap_value_free (exploded_rdn); - } -#else /* HAVE_LDAP_EXPLODE_RDN */ - /* - * we don't have Netscape's ldap_explode_rdn() API, - * so we fudge it with strtok(). Note that this will - * not handle escaping properly. - */ - char *p, *r = *exploded_dn; -#ifdef HAVE_STRTOK_R - char *st = NULL; -#endif /* HAVE_STRTOK_R */ - -#ifndef HAVE_STRTOK_R - for (p = strtok (r, "+"); -#else /* HAVE_STRTOK_R */ - for (p = strtok_r (r, "+", &st); -#endif /* not HAVE_STRTOK_R */ - p != NULL; -#ifndef HAVE_STRTOK_R - p = strtok (NULL, "+")) -#else /* HAVE_STRTOK_R */ - p = strtok_r (NULL, "+", &st)) -#endif /* not HAVE_STRTOK_R */ - { - if (strncasecmp (p, rdnava, rdnavalen) == 0) - { - p += rdnavalen; - rdnlen = strlen (p); - if (*buflen <= rdnlen) - { - ldap_value_free (exploded_dn); - return NSS_STATUS_TRYAGAIN; - } - rdnvalue = *buffer; - strncpy (rdnvalue, p, rdnlen); - break; - } - if (r != NULL) - r = NULL; - } -#endif /* not HAVE_LDAP_EXPLODE_RDN */ - } - - if (exploded_dn != NULL) - { - ldap_value_free (exploded_dn); - } - - if (rdnvalue != NULL) - { - rdnvalue[rdnlen] = '\0'; - *buffer += rdnlen + 1; - *buflen -= rdnlen + 1; - *rval = rdnvalue; - return NSS_STATUS_SUCCESS; - } - - return NSS_STATUS_NOTFOUND; -} - -static enum ldap_map_selector -_nss_ldap_str2selector (const char *key) -{ - enum ldap_map_selector sel; - - if (!strcasecmp (key, MP_passwd)) - sel = LM_PASSWD; - else if (!strcasecmp (key, MP_shadow)) - sel = LM_SHADOW; - else if (!strcasecmp (key, MP_group)) - sel = LM_GROUP; - else if (!strcasecmp (key, MP_hosts)) - sel = LM_HOSTS; - else if (!strcasecmp (key, MP_services)) - sel = LM_SERVICES; - else if (!strcasecmp (key, MP_networks)) - sel = LM_NETWORKS; - else if (!strcasecmp (key, MP_protocols)) - sel = LM_PROTOCOLS; - else if (!strcasecmp (key, MP_rpc)) - sel = LM_RPC; - else if (!strcasecmp (key, MP_ethers)) - sel = LM_ETHERS; - else if (!strcasecmp (key, MP_netmasks)) - sel = LM_NETMASKS; - else if (!strcasecmp (key, MP_bootparams)) - sel = LM_BOOTPARAMS; - else if (!strcasecmp (key, MP_aliases)) - sel = LM_ALIASES; - else if (!strcasecmp (key, MP_netgroup)) - sel = LM_NETGROUP; - else - sel = LM_NONE; - return sel; -} - -static enum nss_status -do_parse_map_statement (struct ldap_config * cfg, - const char *statement, enum ldap_map_type type) -{ - char *key, *val; - enum ldap_map_selector sel = LM_NONE; - - key = (char *) statement; - val = key; - while (*val != ' ' && *val != '\t') - val++; - *(val++) = '\0'; - - while (*val == ' ' || *val == '\t') - val++; - - { - char *p = strchr (key, ':'); - - if (p != NULL) - { - *p = '\0'; - sel = _nss_ldap_str2selector (key); - key = ++p; - } - } - - return _nss_ldap_map_put (cfg, sel, type, key, val); -} - -/* parse a comma-separated list */ -static enum nss_status -do_parse_list (char *values, char ***valptr, - char **pbuffer, size_t *pbuflen) -{ - char *s, **p; -#ifdef HAVE_STRTOK_R - char *tok_r; -#endif /* HAVE_STRTOK_R */ - int valcount; - - int buflen = *pbuflen; - char *buffer = *pbuffer; - - /* comma separated list of values to ignore on initgroups() */ - for (valcount = 1, s = values; *s != '\0'; s++) - { - if (*s == ',') - valcount++; - } - - if (bytesleft (buffer, buflen, char *) < (valcount + 1) * sizeof (char *)) - { - return NSS_STATUS_UNAVAIL; - } - - align (buffer, buflen, char *); - p = *valptr = (char **) buffer; - - buffer += (valcount + 1) * sizeof (char *); - buflen -= (valcount + 1) * sizeof (char *); - -#ifdef HAVE_STRTOK_R - for (s = strtok_r(values, ",", &tok_r); s != NULL; - s = strtok_r(NULL, ",", &tok_r)) -#else /* HAVE_STRTOK_R */ - for (s = strtok(values, ","); s != NULL; s = strtok(NULL, ",")) -#endif /* not HAVE_STRTOK_R */ - { - int vallen; - char *elt = NULL; - - vallen = strlen (s); - if (buflen < (size_t) (vallen + 1)) - { - return NSS_STATUS_UNAVAIL; - } - - /* copy this value into the next block of buffer space */ - elt = buffer; - buffer += vallen + 1; - buflen -= vallen + 1; - - strncpy (elt, s, vallen); - elt[vallen] = '\0'; - *p++ = elt; - } - - *p = NULL; - *pbuffer = buffer; - *pbuflen = buflen; - - return NSS_STATUS_SUCCESS; -} - -static enum nss_status -do_searchdescriptorconfig (const char *key, const char *value, size_t len, - struct ldap_service_search_descriptor ** result, - char **buffer, size_t * buflen) -{ - struct ldap_service_search_descriptor **t, *cur; - char *base; - char *filter, *s; - int scope; - enum ldap_map_selector sel; - - t = NULL; - filter = NULL; - scope = -1; - - if (strncasecmp (key, NSS_LDAP_KEY_NSS_BASE_PREFIX, - NSS_LDAP_KEY_NSS_BASE_PREFIX_LEN) != 0) - return NSS_STATUS_SUCCESS; - - sel = _nss_ldap_str2selector (&key[NSS_LDAP_KEY_NSS_BASE_PREFIX_LEN]); - t = (sel < LM_NONE) ? &result[sel] : NULL; - - if (t == NULL) - return NSS_STATUS_SUCCESS; - - /* we have already checked for room for the value */ - /* len is set to the length of value */ - base = *buffer; - strncpy (base, value, len); - base[len] = '\0'; - - *buffer += len + 1; - *buflen -= len + 1; - - /* probably is some funky escaping needed here. later... */ - s = strchr (base, '?'); - if (s != NULL) - { - *s = '\0'; - s++; - if (!strcasecmp (s, "sub")) - scope = LDAP_SCOPE_SUBTREE; - else if (!strcasecmp (s, "one")) - scope = LDAP_SCOPE_ONELEVEL; - else if (!strcasecmp (s, "base")) - scope = LDAP_SCOPE_BASE; - filter = strchr (s, '?'); - if (filter != NULL) - { - *filter = '\0'; - filter++; - } - } - - if (bytesleft (*buffer, *buflen, struct ldap_service_search_descriptor) < - sizeof (struct ldap_service_search_descriptor)) - return NSS_STATUS_UNAVAIL; - - align (*buffer, *buflen, struct ldap_service_search_descriptor); - - for (cur = *t; cur && cur->lsd_next; cur = cur->lsd_next) - ; - if (!cur) - { - *t = (struct ldap_service_search_descriptor *) * buffer; - cur = *t; - } - else - { - cur->lsd_next = (struct ldap_service_search_descriptor *) * buffer; - cur = cur->lsd_next; - } - - cur->lsd_base = base; - cur->lsd_scope = scope; - cur->lsd_filter = filter; - cur->lsd_next = NULL; - - *buffer += sizeof (struct ldap_service_search_descriptor); - *buflen -= sizeof (struct ldap_service_search_descriptor); - - return NSS_STATUS_SUCCESS; -} - -static enum nss_status _nss_ldap_init_config (struct ldap_config * result) -{ - int i, j; - - memset (result, 0, sizeof (*result)); - - result->ldc_scope = LDAP_SCOPE_SUBTREE; - result->ldc_deref = LDAP_DEREF_NEVER; - result->ldc_base = NULL; - result->ldc_binddn = NULL; - result->ldc_bindpw = NULL; - result->ldc_saslid = NULL; - result->ldc_usesasl = 0; - result->ldc_rootbinddn = NULL; - result->ldc_rootbindpw = NULL; - result->ldc_rootsaslid = NULL; - result->ldc_rootusesasl = 0; -#ifdef LDAP_VERSION3 - result->ldc_version = LDAP_VERSION3; -#else /* LDAP_VERSION3 */ - result->ldc_version = LDAP_VERSION2; -#endif /* not LDAP_VERSION3 */ - result->ldc_timelimit = LDAP_NO_LIMIT; - result->ldc_bind_timelimit = 30; - result->ldc_ssl_on = SSL_OFF; - result->ldc_sslpath = NULL; - result->ldc_referrals = 1; - result->ldc_restart = 1; - result->ldc_tls_checkpeer = -1; - result->ldc_tls_cacertfile = NULL; - result->ldc_tls_cacertdir = NULL; - result->ldc_tls_ciphers = NULL; - result->ldc_tls_cert = NULL; - result->ldc_tls_key = NULL; - result->ldc_tls_randfile = NULL; - result->ldc_idle_timelimit = 0; - result->ldc_reconnect_pol = LP_RECONNECT_HARD_OPEN; - result->ldc_sasl_secprops = NULL; - result->ldc_srv_domain = NULL; - result->ldc_logdir = NULL; - result->ldc_debug = 0; - result->ldc_pagesize = LDAP_PAGESIZE; -#ifdef CONFIGURE_KRB5_CCNAME - result->ldc_krb5_ccname = NULL; -#endif /* CONFIGURE_KRB5_CCNAME */ - result->ldc_flags = 0; -#ifdef RFC2307BIS - result->ldc_flags |= NSS_LDAP_FLAGS_RFC2307BIS; -#endif /* RFC2307BIS */ -#ifdef PAGE_RESULTS - result->ldc_flags |= NSS_LDAP_FLAGS_PAGED_RESULTS; -#endif /* PAGE_RESULTS */ - result->ldc_reconnect_tries = LDAP_NSS_TRIES; - result->ldc_reconnect_sleeptime = LDAP_NSS_SLEEPTIME; - result->ldc_reconnect_maxsleeptime = LDAP_NSS_MAXSLEEPTIME; - result->ldc_reconnect_maxconntries = LDAP_NSS_MAXCONNTRIES; - result->ldc_initgroups_ignoreusers = NULL; - - for (i = 0; i <= LM_NONE; i++) - { - for (j = 0; j <= MAP_MAX; j++) - { - result->ldc_maps[i][j] = (void *)do_alloc_dictionary(); - if (result->ldc_maps[i][j] == NULL) - return NSS_STATUS_UNAVAIL; - } - } - - return NSS_STATUS_SUCCESS; -} - -enum nss_status -_nss_ldap_add_uri (struct ldap_config *result, const char *uri, - char **buffer, size_t *buflen) -{ - /* add a single URI to the list of URIs in the configuration */ - int i; - size_t uri_len; - - debug ("==> _nss_ldap_add_uri"); - - for (i = 0; result->ldc_uris[i] != NULL; i++) - ; - - if (i == NSS_LDAP_CONFIG_URI_MAX) - { - debug ("<== _nss_ldap_add_uri: maximum number of URIs exceeded"); - return NSS_STATUS_UNAVAIL; - } - - assert (i < NSS_LDAP_CONFIG_URI_MAX); - - uri_len = strlen (uri); - - if (*buflen < uri_len + 1) - return NSS_STATUS_TRYAGAIN; - - memcpy (*buffer, uri, uri_len + 1); - - result->ldc_uris[i] = *buffer; - result->ldc_uris[i + 1] = NULL; - - *buffer += uri_len + 1; - *buflen -= uri_len + 1; - - debug ("<== _nss_ldap_add_uri: added URI %s", uri); - - return NSS_STATUS_SUCCESS; -} - -static enum nss_status -do_add_uris (struct ldap_config *result, char *uris, - char **buffer, size_t *buflen) -{ - /* Add a space separated list of URIs */ - char *p; - enum nss_status status = NSS_STATUS_SUCCESS; - - for (p = uris; p != NULL; ) - { - char *q = strchr (p, ' '); - if (q != NULL) - *q = '\0'; - - status = _nss_ldap_add_uri (result, p, buffer, buflen); - - p = (q != NULL) ? ++q : NULL; - - if (status != NSS_STATUS_SUCCESS) - break; - } - - return status; -} - -static enum nss_status -do_add_hosts (struct ldap_config *result, char *hosts, - char **buffer, size_t *buflen) -{ - /* Add a space separated list of hosts */ - char *p; - enum nss_status status = NSS_STATUS_SUCCESS; - - for (p = hosts; p != NULL; ) - { - char b[NSS_LDAP_CONFIG_BUFSIZ]; - char *q = strchr (p, ' '); - - if (q != NULL) - *q = '\0'; - - snprintf (b, sizeof(b), "ldap://%s", p); - - status = _nss_ldap_add_uri (result, b, buffer, buflen); - - p = (q != NULL) ? ++q : NULL; - - if (status != NSS_STATUS_SUCCESS) - break; - } - - return status; -} - -enum nss_status -_nss_ldap_readconfig (struct ldap_config ** presult, char **buffer, size_t *buflen) -{ - FILE *fp; - char b[NSS_LDAP_CONFIG_BUFSIZ]; - enum nss_status status = NSS_STATUS_SUCCESS; - struct ldap_config *result; - struct stat statbuf; - - if (bytesleft (*buffer, *buflen, struct ldap_config *) < sizeof (struct ldap_config)) - { - return NSS_STATUS_TRYAGAIN; - } - align (*buffer, *buflen, struct ldap_config *); - result = *presult = (struct ldap_config *) *buffer; - *buffer += sizeof (struct ldap_config); - *buflen -= sizeof (struct ldap_config); - - status = _nss_ldap_init_config (result); - if (status != NSS_STATUS_SUCCESS) - { - return NSS_STATUS_SUCCESS; - } - - fp = fopen (NSS_LDAP_PATH_CONF, "r"); - if (fp == NULL) - { - return NSS_STATUS_UNAVAIL; - } - - if (fstat (fileno (fp), &statbuf) == 0) - result->ldc_mtime = statbuf.st_mtime; - else - result->ldc_mtime = 0; - - while (fgets (b, sizeof (b), fp) != NULL) - { - char *k, *v; - int len; - char **t = NULL; - - if (*b == '\n' || *b == '\r' || *b == '#') - continue; - - k = b; - v = k; - - /* skip past all characters in keyword */ - while (*v != '\0' && *v != ' ' && *v != '\t') - v++; - - if (*v == '\0') - continue; - - /* terminate keyword */ - *(v++) = '\0'; - - /* skip empty lines with more than 3 spaces at the start of the line */ - /* rds.oliver@samera.com.py 01-set-2004 */ - if (*v == '\n') - continue; - - /* skip all whitespaces between keyword and value */ - /* Lars Oergel <lars.oergel@innominate.de>, 05.10.2000 */ - while (*v == ' ' || *v == '\t') - v++; - - /* kick off all whitespaces and newline at the end of value */ - /* Bob Guo <bob@mail.ied.ac.cn>, 08.10.2001 */ - - /* Also remove \r (CR) to be able to handle files in DOS format (lines - * terminated in CR LF). Alejandro Forero Cuervo - * <azul@freaks-unidos.net>, 10-may-2005 */ - - len = strlen (v) - 1; - while (v[len] == ' ' || v[len] == '\t' || v[len] == '\n' || v[len] == '\r') - --len; - v[++len] = '\0'; - - if (*buflen < (size_t) (len + 1)) - { - status = NSS_STATUS_TRYAGAIN; - break; - } - - if (!strcasecmp (k, NSS_LDAP_KEY_HOST)) - { - status = do_add_hosts (result, v, buffer, buflen); - if (status != NSS_STATUS_SUCCESS) - break; - } - else if (!strcasecmp (k, NSS_LDAP_KEY_URI)) - { - status = do_add_uris (result, v, buffer, buflen); - if (status != NSS_STATUS_SUCCESS) - break; - } - else if (!strcasecmp (k, NSS_LDAP_KEY_BASE)) - { - t = &result->ldc_base; - } - else if (!strcasecmp (k, NSS_LDAP_KEY_BINDDN)) - { - t = &result->ldc_binddn; - } - else if (!strcasecmp (k, NSS_LDAP_KEY_BINDPW)) - { - t = &result->ldc_bindpw; - } - else if (!strcasecmp (k, NSS_LDAP_KEY_USESASL)) - { - result->ldc_usesasl = (!strcasecmp (v, "on") - || !strcasecmp (v, "yes") - || !strcasecmp (v, "true")); - } - else if (!strcasecmp (k, NSS_LDAP_KEY_SASLID)) - { - t = &result->ldc_saslid; - } - else if (!strcasecmp (k, NSS_LDAP_KEY_ROOTBINDDN)) - { - t = &result->ldc_rootbinddn; - } - else if (!strcasecmp (k, NSS_LDAP_KEY_ROOTUSESASL)) - { - result->ldc_rootusesasl = (!strcasecmp (v, "on") - || !strcasecmp (v, "yes") - || !strcasecmp (v, "true")); - } - else if (!strcasecmp (k, NSS_LDAP_KEY_ROOTSASLID)) - { - t = &result->ldc_rootsaslid; - } - else if (!strcasecmp (k, NSS_LDAP_KEY_SSLPATH)) - { - t = &result->ldc_sslpath; - } - else if (!strcasecmp (k, NSS_LDAP_KEY_SCOPE)) - { - if (!strcasecmp (v, "sub")) - { - result->ldc_scope = LDAP_SCOPE_SUBTREE; - } - else if (!strcasecmp (v, "one")) - { - result->ldc_scope = LDAP_SCOPE_ONELEVEL; - } - else if (!strcasecmp (v, "base")) - { - result->ldc_scope = LDAP_SCOPE_BASE; - } - } - else if (!strcasecmp (k, NSS_LDAP_KEY_DEREF)) - { - if (!strcasecmp (v, "never")) - { - result->ldc_deref = LDAP_DEREF_NEVER; - } - else if (!strcasecmp (v, "searching")) - { - result->ldc_deref = LDAP_DEREF_SEARCHING; - } - else if (!strcasecmp (v, "finding")) - { - result->ldc_deref = LDAP_DEREF_FINDING; - } - else if (!strcasecmp (v, "always")) - { - result->ldc_deref = LDAP_DEREF_ALWAYS; - } - } - else if (!strcasecmp (k, NSS_LDAP_KEY_PORT)) - { - result->ldc_port = atoi (v); - } - else if (!strcasecmp (k, NSS_LDAP_KEY_SSL)) - { - if (!strcasecmp (v, "on") || !strcasecmp (v, "yes") - || !strcasecmp (v, "true")) - { - result->ldc_ssl_on = SSL_LDAPS; - } - else if (!strcasecmp (v, "start_tls")) - { - result->ldc_ssl_on = SSL_START_TLS; - } - } - else if (!strcasecmp (k, NSS_LDAP_KEY_REFERRALS)) - { - result->ldc_referrals = (!strcasecmp (v, "on") - || !strcasecmp (v, "yes") - || !strcasecmp (v, "true")); - } - else if (!strcasecmp (k, NSS_LDAP_KEY_RESTART)) - { - result->ldc_restart = (!strcasecmp (v, "on") - || !strcasecmp (v, "yes") - || !strcasecmp (v, "true")); - } - else if (!strcasecmp (k, NSS_LDAP_KEY_LDAP_VERSION)) - { - result->ldc_version = atoi (v); - } - else if (!strcasecmp (k, NSS_LDAP_KEY_TIMELIMIT)) - { - result->ldc_timelimit = atoi (v); - } - else if (!strcasecmp (k, NSS_LDAP_KEY_BIND_TIMELIMIT)) - { - result->ldc_bind_timelimit = atoi (v); - } - else if (!strcasecmp (k, NSS_LDAP_KEY_IDLE_TIMELIMIT)) - { - result->ldc_idle_timelimit = atoi (v); - } - else if (!strcasecmp (k, NSS_LDAP_KEY_RECONNECT_POLICY)) - { - if (!strcasecmp (v, "hard") || - !strcasecmp (v, "hard_open")) - { - result->ldc_reconnect_pol = LP_RECONNECT_HARD_OPEN; - } - else if (!strcasecmp (v, "hard_init")) - { - result->ldc_reconnect_pol = LP_RECONNECT_HARD_INIT; - } - else if (!strcasecmp (v, "soft")) - { - result->ldc_reconnect_pol = LP_RECONNECT_SOFT; - } - } - else if (!strcasecmp (k, NSS_LDAP_KEY_RECONNECT_TRIES)) - { - result->ldc_reconnect_tries = atoi (v); - } - else if (!strcasecmp (k, NSS_LDAP_KEY_RECONNECT_SLEEPTIME)) - { - result->ldc_reconnect_sleeptime = atoi (v); - } - else if (!strcasecmp (k, NSS_LDAP_KEY_RECONNECT_MAXSLEEPTIME)) - { - result->ldc_reconnect_maxsleeptime = atoi (v); - } - else if (!strcasecmp (k, NSS_LDAP_KEY_RECONNECT_MAXCONNTRIES)) - { - result->ldc_reconnect_maxconntries = atoi (v); - } - else if (!strcasecmp (k, NSS_LDAP_KEY_SASL_SECPROPS)) - { - t = &result->ldc_sasl_secprops; - } - else if (!strcasecmp (k, NSS_LDAP_KEY_LOGDIR)) - { - t = &result->ldc_logdir; - } - else if (!strcasecmp (k, NSS_LDAP_KEY_DEBUG)) - { - result->ldc_debug = atoi (v); - } - else if (!strcasecmp (k, NSS_LDAP_KEY_PAGESIZE)) - { - result->ldc_pagesize = atoi (v); - } -#ifdef CONFIGURE_KRB5_CCNAME - else if (!strcasecmp (k, NSS_LDAP_KEY_KRB5_CCNAME)) - { - t = &result->ldc_krb5_ccname; - } -#endif /* CONFIGURE_KRB5_CCNAME */ - else if (!strcasecmp (k, "tls_checkpeer")) - { - if (!strcasecmp (v, "on") || !strcasecmp (v, "yes") - || !strcasecmp (v, "true")) - { - result->ldc_tls_checkpeer = 1; - } - else if (!strcasecmp (v, "off") || !strcasecmp (v, "no") - || !strcasecmp (v, "false")) - { - result->ldc_tls_checkpeer = 0; - } - } - else if (!strcasecmp (k, "tls_cacertfile")) - { - t = &result->ldc_tls_cacertfile; - } - else if (!strcasecmp (k, "tls_cacertdir")) - { - t = &result->ldc_tls_cacertdir; - } - else if (!strcasecmp (k, "tls_ciphers")) - { - t = &result->ldc_tls_ciphers; - } - else if (!strcasecmp (k, "tls_cert")) - { - t = &result->ldc_tls_cert; - } - else if (!strcasecmp (k, "tls_key")) - { - t = &result->ldc_tls_key; - } - else if (!strcasecmp (k, "tls_randfile")) - { - t = &result->ldc_tls_randfile; - } - else if (!strncasecmp (k, NSS_LDAP_KEY_MAP_ATTRIBUTE, - strlen (NSS_LDAP_KEY_MAP_ATTRIBUTE))) - { - do_parse_map_statement (result, v, MAP_ATTRIBUTE); - } - else if (!strncasecmp (k, NSS_LDAP_KEY_MAP_OBJECTCLASS, - strlen (NSS_LDAP_KEY_MAP_OBJECTCLASS))) - { - do_parse_map_statement (result, v, MAP_OBJECTCLASS); - } - else if (!strncasecmp (k, NSS_LDAP_KEY_SET_OVERRIDE, - strlen (NSS_LDAP_KEY_SET_OVERRIDE))) - { - do_parse_map_statement (result, v, MAP_OVERRIDE); - } - else if (!strncasecmp (k, NSS_LDAP_KEY_SET_DEFAULT, - strlen (NSS_LDAP_KEY_SET_DEFAULT))) - { - do_parse_map_statement (result, v, MAP_DEFAULT); - } - else if (!strcasecmp (k, NSS_LDAP_KEY_INITGROUPS)) - { - if (!strcasecmp (v, "backlink")) - { - result->ldc_flags |= NSS_LDAP_FLAGS_INITGROUPS_BACKLINK; - } - else - { - result->ldc_flags &= ~(NSS_LDAP_FLAGS_INITGROUPS_BACKLINK); - } - } - else if (!strcasecmp (k, NSS_LDAP_KEY_SCHEMA)) - { - if (!strcasecmp (v, "rfc2307bis")) - { - result->ldc_flags |= NSS_LDAP_FLAGS_RFC2307BIS; - } - else if (!strcasecmp (v, "rfc2307")) - { - result->ldc_flags &= ~(NSS_LDAP_FLAGS_RFC2307BIS); - } - } - else if (!strcasecmp (k, NSS_LDAP_KEY_PAGED_RESULTS)) - { - if (!strcasecmp (v, "on") - || !strcasecmp (v, "yes") - || !strcasecmp (v, "true")) - { - result->ldc_flags |= NSS_LDAP_FLAGS_PAGED_RESULTS; - } - else - { - result->ldc_flags &= ~(NSS_LDAP_FLAGS_PAGED_RESULTS); - } - } - else if (!strcasecmp (k, NSS_LDAP_KEY_INITGROUPS_IGNOREUSERS)) - { - status = do_parse_list (v, &result->ldc_initgroups_ignoreusers, - buffer, buflen); - if (status == NSS_STATUS_UNAVAIL) - { - break; - } - } - else if (!strcasecmp (k, NSS_LDAP_KEY_CONNECT_POLICY)) - { - if (!strcasecmp (v, "oneshot")) - { - result->ldc_flags |= NSS_LDAP_FLAGS_CONNECT_POLICY_ONESHOT; - } - else if (!strcasecmp (v, "persist")) - { - result->ldc_flags &= ~(NSS_LDAP_FLAGS_CONNECT_POLICY_ONESHOT); - } - } - else if (!strcasecmp (k, NSS_LDAP_KEY_SRV_DOMAIN)) - { - t = &result->ldc_srv_domain; - } - else - { - /* - * check whether the key is a naming context key - * if yes, parse; otherwise just return NSS_STATUS_SUCCESS - * so we can ignore keys we don't understand. - */ - status = - do_searchdescriptorconfig (k, v, len, result->ldc_sds, - buffer, buflen); - if (status == NSS_STATUS_UNAVAIL) - { - break; - } - } - - if (t != NULL) - { - strncpy (*buffer, v, len); - (*buffer)[len] = '\0'; - *t = *buffer; - *buffer += len + 1; - *buflen -= len + 1; - } - } - - fclose (fp); - - if (status != NSS_STATUS_SUCCESS) - { - return status; - } - - if (result->ldc_rootbinddn != NULL) - { - fp = fopen (NSS_LDAP_PATH_ROOTPASSWD, "r"); - if (fp) - { - if (fgets (b, sizeof (b), fp) != NULL) - { - int len; - - len = strlen (b); - /* BUG#138: check for newline before removing */ - if (len > 0 && b[len - 1] == '\n') - len--; - - if (*buflen < (size_t) (len + 1)) - { - return NSS_STATUS_UNAVAIL; - } - - strncpy (*buffer, b, len); - (*buffer)[len] = '\0'; - result->ldc_rootbindpw = *buffer; - *buffer += len + 1; - *buflen -= len + 1; - } - fclose (fp); - } - else if (!result->ldc_rootusesasl) - { - result->ldc_rootbinddn = NULL; - } - } - - if (result->ldc_port == 0) - { - if (result->ldc_ssl_on == SSL_LDAPS) - { - result->ldc_port = LDAPS_PORT; - } - else - { - result->ldc_port = LDAP_PORT; - } - } - - if (result->ldc_uris[0] == NULL) - { - status = NSS_STATUS_NOTFOUND; - } - - return status; -} - -enum nss_status -_nss_ldap_escape_string (const char *str, char *buf, size_t buflen) -{ - int ret = NSS_STATUS_TRYAGAIN; - char *p = buf; - char *limit = p + buflen - 3; - const char *s = str; - - while (p < limit && *s) - { - switch (*s) - { - case '*': - strcpy (p, "\\2a"); - p += 3; - break; - case '(': - strcpy (p, "\\28"); - p += 3; - break; - case ')': - strcpy (p, "\\29"); - p += 3; - break; - case '\\': - strcpy (p, "\\5c"); - p += 3; - break; - default: - *p++ = *s; - break; - } - s++; - } - - if (*s == '\0') - { - /* got to end */ - *p = '\0'; - ret = NSS_STATUS_SUCCESS; - } - - return ret; -} - -/* XXX just a linked list for now */ - -struct ldap_dictionary -{ - struct ldap_datum key; - struct ldap_datum value; - struct ldap_dictionary *next; -}; - -static struct ldap_dictionary *do_alloc_dictionary(void) -{ - struct ldap_dictionary *dict; - - dict = malloc (sizeof (*dict)); - if (dict == NULL) - { - return NULL; - } - NSS_LDAP_DATUM_ZERO (&dict->key); - NSS_LDAP_DATUM_ZERO (&dict->value); - dict->next = NULL; - - return dict; -} - -static void -do_free_datum (struct ldap_datum * datum) -{ - if (datum->data != NULL) - { - free (datum->data); - datum->data = NULL; - } - datum->size = 0; -} - -static struct ldap_dictionary * -do_find_last (struct ldap_dictionary *dict) -{ - struct ldap_dictionary *p; - - for (p = dict; p->next != NULL; p = p->next) - ; - - return p; -} - -static void -do_free_dictionary (struct ldap_dictionary *dict) -{ - do_free_datum (&dict->key); - do_free_datum (&dict->value); - free (dict); -} - -static enum nss_status -do_dup_datum (unsigned flags, struct ldap_datum * dst, const struct ldap_datum * src) -{ - dst->data = malloc (src->size); - if (dst->data == NULL) - return NSS_STATUS_TRYAGAIN; - - memcpy (dst->data, src->data, src->size); - dst->size = src->size; - - return NSS_STATUS_SUCCESS; -} - -enum nss_status -_nss_ldap_db_get (void *db, - unsigned flags, - const struct ldap_datum * key, - struct ldap_datum * value) -{ - struct ldap_dictionary *dict = (struct ldap_dictionary *) db; - struct ldap_dictionary *p; - - for (p = dict; p != NULL; p = p->next) - { - int cmp; - - if (p->key.size != key->size) - continue; - - if (flags & NSS_LDAP_DB_NORMALIZE_CASE) - cmp = strncasecmp ((char *)p->key.data, (char *)key->data, key->size); - else - cmp = memcmp (p->key.data, key->data, key->size); - - if (cmp == 0) - { - value->data = p->value.data; - value->size = p->value.size; - - return NSS_STATUS_SUCCESS; - } - } - - return NSS_STATUS_NOTFOUND; -} - -enum nss_status -_nss_ldap_db_put (void *db, - unsigned flags, - const struct ldap_datum * key, - const struct ldap_datum * value) -{ - struct ldap_dictionary *dict = (struct ldap_dictionary *) db; - struct ldap_dictionary *p, *q; - - assert (key != NULL); - assert (key->data != NULL); - - if (dict->key.data == NULL) - { - /* uninitialized */ - q = dict; - p = NULL; - } - else - { - p = do_find_last (dict); - assert (p != NULL); - assert (p->next == NULL); - q = do_alloc_dictionary(); - if (q == NULL) - return NSS_STATUS_TRYAGAIN; - } - - if (do_dup_datum (flags, &q->key, key) != NSS_STATUS_SUCCESS) - { - do_free_dictionary (q); - return NSS_STATUS_TRYAGAIN; - } - - if (do_dup_datum (flags, &q->value, value) != NSS_STATUS_SUCCESS) - { - do_free_dictionary (q); - return NSS_STATUS_TRYAGAIN; - } - - if (p != NULL) - p->next = q; - - return NSS_STATUS_SUCCESS; -} - -/* - * Add a nested netgroup or group to the namelist - */ -enum nss_status -_nss_ldap_namelist_push (struct name_list **head, const char *name) -{ - struct name_list *nl; - - debug ("==> _nss_ldap_namelist_push (%s)", name); - - nl = (struct name_list *) malloc (sizeof (*nl)); - if (nl == NULL) - { - debug ("<== _nss_ldap_namelist_push"); - return NSS_STATUS_TRYAGAIN; - } - - nl->name = strdup (name); - if (nl->name == NULL) - { - debug ("<== _nss_ldap_namelist_push"); - free (nl); - return NSS_STATUS_TRYAGAIN; - } - - nl->next = *head; - - *head = nl; - - debug ("<== _nss_ldap_namelist_push"); - - return NSS_STATUS_SUCCESS; -} - -/* - * Remove last nested netgroup or group from the namelist - */ -void -_nss_ldap_namelist_pop (struct name_list **head) -{ - struct name_list *nl; - - debug ("==> _nss_ldap_namelist_pop"); - - assert (*head != NULL); - nl = *head; - - *head = nl->next; - - assert (nl->name != NULL); - free (nl->name); - free (nl); - - debug ("<== _nss_ldap_namelist_pop"); -} - -/* - * Cleanup nested netgroup or group namelist. - */ -void -_nss_ldap_namelist_destroy (struct name_list **head) -{ - struct name_list *p, *next; - - debug ("==> _nss_ldap_namelist_destroy"); - - for (p = *head; p != NULL; p = next) - { - next = p->next; - - if (p->name != NULL) - free (p->name); - free (p); - } - - *head = NULL; - - debug ("<== _nss_ldap_namelist_destroy"); -} - -/* - * Check whether we have already seen a netgroup or group, - * to avoid loops in nested netgroup traversal - */ -int -_nss_ldap_namelist_find (struct name_list *head, const char *netgroup) -{ - struct name_list *p; - int found = 0; - - debug ("==> _nss_ldap_namelist_find"); - - for (p = head; p != NULL; p = p->next) - { - if (strcasecmp (p->name, netgroup) == 0) - { - found++; - break; - } - } - - debug ("<== _nss_ldap_namelist_find"); - - return found; -} - -enum nss_status _nss_ldap_validateconfig (struct ldap_config *config) -{ - struct stat statbuf; - - if (config == NULL) - { - return NSS_STATUS_UNAVAIL; - } - - if (config->ldc_mtime == 0) - { - return NSS_STATUS_SUCCESS; - } - - if (stat (NSS_LDAP_PATH_CONF, &statbuf) == 0) - { - return (statbuf.st_mtime > config->ldc_mtime) ? NSS_STATUS_TRYAGAIN : NSS_STATUS_SUCCESS; - } - - return NSS_STATUS_SUCCESS; -} - diff --git a/server/util.h b/server/util.h deleted file mode 100644 index f193916..0000000 --- a/server/util.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - util.h - LDAP utility functions - This file was part of the nss_ldap library which has been - forked into the nss-ldapd library. - - Copyright (C) 1997-2005 Luke Howard - Copyright (C) 2006 West Consulting - Copyright (C) 2006 Arthur de Jong - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1301 USA -*/ - -#ifndef _LDAP_NSS_LDAP_UTIL_H -#define _LDAP_NSS_LDAP_UTIL_H - -/* - * get the RDN's value: eg. if the RDN was cn=lukeh, getrdnvalue(entry) - * would return lukeh. - */ -enum nss_status _nss_ldap_getrdnvalue(LDAPMessage *entry, - const char *rdntype, - char **rval, char **buf, size_t * len); - -int _nss_ldap_write_rndvalue(FILE *fp,LDAPMessage *entry,const char *rdntype); - -/* - * map a distinguished name to a login name, or group entry - */ -enum nss_status _nss_ldap_dn2uid (const char *dn, - char **uid, char **buf, size_t * len, - int *pIsNestedGroup, LDAPMessage ** pRes); - - -#define NSS_LDAP_CONFIG_BUFSIZ 4096 - -/* - * support separate naming contexts for each map - * eventually this will support the syntax defined in - * the DUAConfigProfile searchDescriptor attribute - */ -#define NSS_LDAP_KEY_NSS_BASE_PREFIX "nss_base_" -#define NSS_LDAP_KEY_NSS_BASE_PREFIX_LEN ( sizeof(NSS_LDAP_KEY_NSS_BASE_PREFIX) - 1 ) - -/* - * Flags that are exposed via _nss_ldap_test_config_flag() - */ -#define NSS_LDAP_FLAGS_INITGROUPS_BACKLINK 0x0001 -#define NSS_LDAP_FLAGS_PAGED_RESULTS 0x0002 -#define NSS_LDAP_FLAGS_RFC2307BIS 0x0004 -#define NSS_LDAP_FLAGS_CONNECT_POLICY_ONESHOT 0x0008 - -/* - * There are a number of means of obtaining configuration information. - * - * (a) DHCP (Cf draft-hedstrom-dhc-ldap-00.txt) - * (b) a configuration file (/etc/ldap.conf) ** - * (c) a coldstart file & subsequent referrals from the LDAP server - * (d) a custom LDAP bind protocol - * (e) DNS ** - * - * This should be opaque to the rest of the library. - * ** implemented - */ - -enum nss_status _nss_ldap_readconfig (struct ldap_config ** result, char **buffer, size_t *buflen); -enum nss_status _nss_ldap_validateconfig (struct ldap_config *config); - -/* - * Escape '*' in a string for use as a filter - */ - -enum nss_status _nss_ldap_escape_string (const char *str, - char *buf, size_t buflen); - -struct ldap_datum -{ - void *data; - size_t size; -}; - -#define NSS_LDAP_DATUM_ZERO(d) do { \ - (d)->data = NULL; \ - (d)->size = 0; \ - } while (0) - -#define NSS_LDAP_DB_NORMALIZE_CASE 0x1 - -enum nss_status _nss_ldap_db_put (void *db, - unsigned flags, - const struct ldap_datum * key, - const struct ldap_datum * value); -enum nss_status _nss_ldap_db_get (void *db, - unsigned flags, - const struct ldap_datum * key, - struct ldap_datum * value); - -/* Routines for managing namelists */ - -enum nss_status _nss_ldap_namelist_push (struct name_list **head, const char *name); -void _nss_ldap_namelist_pop (struct name_list **head); -int _nss_ldap_namelist_find (struct name_list *head, const char *netgroup); -void _nss_ldap_namelist_destroy (struct name_list **head); - -enum nss_status -_nss_ldap_add_uri (struct ldap_config *result, const char *uri, - char **buffer, size_t *buflen); - -#endif /* _LDAP_NSS_LDAP_UTIL_H */ diff --git a/server/xmalloc.c b/server/xmalloc.c deleted file mode 100644 index 9dbd9a4..0000000 --- a/server/xmalloc.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - xmalloc.c - malloc wrapper - - Copyright (C) 2002, 2003, 2006 Arthur de Jong - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1301 USA -*/ - -#include "config.h" - -#include <stdlib.h> -#include <string.h> - -#include "xmalloc.h" -#include "log.h" - - -/* malloc wrapper */ -void *xmalloc(size_t size) -{ - void *tmp; - if ((tmp=malloc(size))==NULL) - { - log_log(LOG_CRIT,"malloc() failed"); - exit(1); - } - return tmp; -} - - -/* strdup wrapper */ -char *xstrdup(const char *s) -{ - char *tmp; - int l; - if (s==NULL) - { - log_log(LOG_CRIT,"xstrdup() called with NULL"); - exit(1); - } - l=strlen(s); - tmp=(char *)xmalloc((l+1)*sizeof(char)); - strncpy(tmp,s,l); - tmp[l]='\0'; - return tmp; -} diff --git a/server/xmalloc.h b/server/xmalloc.h deleted file mode 100644 index 04ad025..0000000 --- a/server/xmalloc.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - xmalloc.h - malloc wrapper - - Copyright (C) 2002 Arthur de Jong - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1301 USA -*/ - -#ifndef _XMALLOC_H -#define _XMALLOC_H 1 - -#include <stdlib.h> - -/* malloc wrapper */ -void *xmalloc(size_t size); - -/* allocate size for a specific type */ -#define xxmalloc(type,count) (type *)xmalloc(sizeof(type)*(count)) - -/* strdup wrapper */ -char *xstrdup(const char *s); - -#endif /* not _XMALLOC_H */ |