summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArthur de Jong <arthur@arthurdejong.org>2007-01-17 16:03:11 +0000
committerArthur de Jong <arthur@arthurdejong.org>2007-01-17 16:03:11 +0000
commitd2296ccd7c8bfdfffe4dc99c4c4db32eaae4c60b (patch)
treee35d6b53cc0b53c7425f8bf8f3923c28fc34562d
parentc026629eedf04f9d3579180980bb6bfa6759d15b (diff)
move most config code into cfg.c, clean up dictornary stuff in util.c and do some more smaller restructuring
git-svn-id: http://arthurdejong.org/svn/nss-pam-ldapd/nss-ldapd@223 ef36b2f9-881f-0410-afb5-c4e39611909c
-rw-r--r--nslcd/cfg.c1000
-rw-r--r--nslcd/cfg.h12
-rw-r--r--nslcd/group.c15
-rw-r--r--nslcd/ldap-nss.c348
-rw-r--r--nslcd/util.c1364
-rw-r--r--nslcd/util.h43
6 files changed, 1348 insertions, 1434 deletions
diff --git a/nslcd/cfg.c b/nslcd/cfg.c
index 37f7d8c..ba5e875 100644
--- a/nslcd/cfg.c
+++ b/nslcd/cfg.c
@@ -26,6 +26,12 @@
#include "config.h"
#include <string.h>
+#include <stdio.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdlib.h>
#include "ldap-nss.h"
#include "util.h"
@@ -34,28 +40,951 @@
struct ldap_config *nslcd_cfg=NULL;
-int _nss_ldap_test_config_flag (unsigned int flag)
+#define LDAP_PAGESIZE 1000
+
+/*
+ * 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 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"
+
+/*
+ * 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 )
+
+#define NSS_LDAP_CONFIG_BUFSIZ 4096
+
+int _nss_ldap_test_config_flag(unsigned int flag)
{
return nslcd_cfg != NULL &&
(nslcd_cfg->ldc_flags&flag);
}
-int _nss_ldap_test_initgroups_ignoreuser(const char *user)
+static enum nss_status _nss_ldap_init_config(struct ldap_config *result)
{
- char **p;
- if (nslcd_cfg == NULL)
- return 0;
+ int i, j;
- if (nslcd_cfg->ldc_initgroups_ignoreusers == NULL)
- return 0;
+ memset (result, 0, sizeof (*result));
- for (p = nslcd_cfg->ldc_initgroups_ignoreusers; *p != NULL; p++)
+ 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++)
{
- if (strcmp (*p, user) == 0)
- return 1;
+ result->ldc_maps[i][j]=(void *)dict_new();
+ if (result->ldc_maps[i][j] == NULL)
+ return NSS_STATUS_UNAVAIL;
}
+ }
- return 0;
+ return NSS_STATUS_SUCCESS;
+}
+
+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;
+}
+
+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 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 _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 retv;
+
+ 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;
+
+ retv = dict_put (*map, NSS_LDAP_DB_NORMALIZE_CASE, &key, &val);
+ if (retv == 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];
+
+ retv = dict_put (*map, NSS_LDAP_DB_NORMALIZE_CASE, &val, &key);
+ }
+
+ return retv;
+}
+
+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;
+ char *p;
+ key=(char *)statement;
+ val=key;
+ while (*val!=' '&&*val!='\t')
+ val++;
+ *(val++)='\0';
+ while (*val==' '||*val=='\t')
+ val++;
+ 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_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;
}
int cfg_init(void)
@@ -63,18 +992,18 @@ int cfg_init(void)
static char configbuf[NSS_LDAP_CONFIG_BUFSIZ];
char *configbufp;
size_t configbuflen;
- enum nss_status stat;
+ enum nss_status retv;
if (nslcd_cfg==NULL)
{
configbufp=configbuf;
configbuflen=sizeof(configbuf);
- stat=_nss_ldap_readconfig(&nslcd_cfg,&configbufp,&configbuflen);
- if (stat==NSS_STATUS_NOTFOUND)
+ retv=_nss_ldap_readconfig(&nslcd_cfg,&configbufp,&configbuflen);
+ if (retv==NSS_STATUS_NOTFOUND)
{
/* config was read but no host information specified; try DNS */
- stat=_nss_ldap_mergeconfigfromdns(nslcd_cfg,&configbufp,&configbuflen);
+ retv=_nss_ldap_mergeconfigfromdns(nslcd_cfg,&configbufp,&configbuflen);
}
- if (stat != NSS_STATUS_SUCCESS)
+ if (retv!=NSS_STATUS_SUCCESS)
{
log_log(LOG_DEBUG,"cfg_init() failed to read config");
return -1;
@@ -82,3 +1011,42 @@ int cfg_init(void)
}
return 0;
}
+
+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;
+
+ log_log(LOG_DEBUG,"==> _nss_ldap_add_uri");
+
+ for (i = 0; result->ldc_uris[i] != NULL; i++)
+ ;
+
+ if (i == NSS_LDAP_CONFIG_URI_MAX)
+ {
+ log_log(LOG_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;
+
+ log_log(LOG_DEBUG,"<== _nss_ldap_add_uri: added URI %s", uri);
+
+ return NSS_STATUS_SUCCESS;
+}
diff --git a/nslcd/cfg.h b/nslcd/cfg.h
index 5703701..71b552e 100644
--- a/nslcd/cfg.h
+++ b/nslcd/cfg.h
@@ -152,12 +152,18 @@ extern struct ldap_config *nslcd_cfg;
* ** 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);
+/*
+ * 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
int _nss_ldap_test_config_flag(unsigned int flag);
-int _nss_ldap_test_initgroups_ignoreuser(const char *user);
int cfg_init(void);
+enum nss_status _nss_ldap_add_uri (struct ldap_config *result, const char *uri,char **buffer, size_t *buflen);
+
#endif /* _CFG_H */
diff --git a/nslcd/group.c b/nslcd/group.c
index 1c92987..5753932 100644
--- a/nslcd/group.c
+++ b/nslcd/group.c
@@ -48,6 +48,7 @@
#include "util.h"
#include "common.h"
#include "log.h"
+#include "cfg.h"
struct name_list
{
@@ -998,6 +999,20 @@ static enum nss_status ng_chase_backlink(const char ** membersOf, ldap_initgroup
return stat;
}
+static int _nss_ldap_test_initgroups_ignoreuser(const char *user)
+{
+ char **p;
+ if (nslcd_cfg == NULL)
+ return 0;
+ if (nslcd_cfg->ldc_initgroups_ignoreusers == NULL)
+ return 0;
+ for (p = nslcd_cfg->ldc_initgroups_ignoreusers; *p != NULL; p++)
+ {
+ if (strcmp (*p, user) == 0)
+ return 1;
+ }
+ return 0;
+}
static enum nss_status group_bymember(const char *user, long int *start,
long int *size, long int limit,
diff --git a/nslcd/ldap-nss.c b/nslcd/ldap-nss.c
index f5f6e4c..7423617 100644
--- a/nslcd/ldap-nss.c
+++ b/nslcd/ldap-nss.c
@@ -82,7 +82,6 @@
#include "ldap-nss.h"
#include "util.h"
-#include "dnsconfig.h"
#include "pagectrl.h"
#include "common.h"
#include "log.h"
@@ -148,14 +147,6 @@ static void do_close (void);
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.
@@ -393,6 +384,72 @@ do_bind (LDAP * ld, int timelimit, const char *dn, const char *pw,
return -1;
}
+#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;
+
+ log_log(LOG_DEBUG,"==> do_start_tls");
+
+ rc=ldap_start_tls(session->ls_conn, NULL, NULL, &msgid);
+ if (rc != LDAP_SUCCESS)
+ {
+ log_log(LOG_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 */
+ log_log(LOG_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)
+ {
+ log_log(LOG_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)
+ {
+ log_log(LOG_DEBUG,"<== do_start_tls (start TLS failed: %s)",ldap_err2string(rc));
+ return rc;
+ }
+
+ return LDAP_SUCCESS;
+}
+#endif
+
/*
* Rebind functions.
*/
@@ -860,70 +917,83 @@ _nss_ldap_init (void)
return do_init ();
}
-#if defined(HAVE_LDAP_START_TLS_S) || defined(HAVE_LDAP_START_TLS)
-static int
-do_start_tls (struct ldap_session * session)
+#if defined HAVE_LDAP_START_TLS_S || (defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS))
+static int do_ssl_options(void)
{
- int rc;
-#ifdef HAVE_LDAP_START_TLS
- int msgid;
- struct timeval tv, *timeout;
- LDAPMessage *res = NULL;
-
- log_log(LOG_DEBUG,"==> do_start_tls");
-
- rc = ldap_start_tls (session->ls_conn, NULL, NULL, &msgid);
- if (rc != LDAP_SUCCESS)
- {
- log_log(LOG_DEBUG,"<== do_start_tls (ldap_start_tls failed: %s)", ldap_err2string (rc));
- return rc;
- }
-
- if (session->ls_config->ldc_bind_timelimit == LDAP_NO_LIMIT)
+ log_log(LOG_DEBUG,"==> do_ssl_options");
+#ifdef LDAP_OPT_X_TLS_RANDOM_FILE
+ if (nslcd_cfg->ldc_tls_randfile!=NULL)
+ {
+ /* rand file */
+ if (ldap_set_option(NULL,LDAP_OPT_X_TLS_RANDOM_FILE,
+ nslcd_cfg->ldc_tls_randfile)!=LDAP_SUCCESS)
{
- timeout = NULL;
+ log_log(LOG_DEBUG,"<== do_ssl_options: Setting of LDAP_OPT_X_TLS_RANDOM_FILE failed");
+ return LDAP_OPERATIONS_ERROR;
}
- else
+ }
+#endif /* LDAP_OPT_X_TLS_RANDOM_FILE */
+ if (nslcd_cfg->ldc_tls_cacertfile!=NULL)
+ {
+ /* ca cert file */
+ if (ldap_set_option(NULL,LDAP_OPT_X_TLS_CACERTFILE,
+ nslcd_cfg->ldc_tls_cacertfile)!=LDAP_SUCCESS)
{
- tv.tv_sec = session->ls_config->ldc_bind_timelimit;
- tv.tv_usec = 0;
- timeout = &tv;
+ log_log(LOG_DEBUG,"<== do_ssl_options: Setting of LDAP_OPT_X_TLS_CACERTFILE failed");
+ return LDAP_OPERATIONS_ERROR;
}
-
- rc = ldap_result (session->ls_conn, msgid, 1, timeout, &res);
- if (rc == -1)
+ }
+ if (nslcd_cfg->ldc_tls_cacertdir!=NULL)
+ {
+ /* ca cert directory */
+ if (ldap_set_option(NULL,LDAP_OPT_X_TLS_CACERTDIR,
+ nslcd_cfg->ldc_tls_cacertdir)!=LDAP_SUCCESS)
{
-#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 */
-
- log_log(LOG_DEBUG,"<== do_start_tls (ldap_start_tls failed: %s)", ldap_err2string (rc));
- return rc;
+ log_log(LOG_DEBUG,"<== do_ssl_options: Setting of LDAP_OPT_X_TLS_CACERTDIR failed");
+ return LDAP_OPERATIONS_ERROR;
}
-
- rc = ldap_result2error (session->ls_conn, res, 1);
- if (rc != LDAP_SUCCESS)
+ }
+ /* require cert? */
+ if (nslcd_cfg->ldc_tls_checkpeer > -1)
+ {
+ if (ldap_set_option(NULL,LDAP_OPT_X_TLS_REQUIRE_CERT,
+ &nslcd_cfg->ldc_tls_checkpeer)!=LDAP_SUCCESS)
{
- log_log(LOG_DEBUG,"<== do_start_tls (ldap_result2error failed: %s)", ldap_err2string (rc));
- return rc;
+ log_log(LOG_DEBUG,"<== do_ssl_options: Setting of LDAP_OPT_X_TLS_REQUIRE_CERT failed");
+ return LDAP_OPERATIONS_ERROR;
}
+ }
- 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)
- {
- log_log(LOG_DEBUG,"<== do_start_tls (start TLS failed: %s)", ldap_err2string(rc));
- return rc;
- }
+ if (nslcd_cfg->ldc_tls_ciphers != NULL)
+ {
+ /* set cipher suite, certificate and private key: */
+ if (ldap_set_option(NULL,LDAP_OPT_X_TLS_CIPHER_SUITE,
+ nslcd_cfg->ldc_tls_ciphers)!=LDAP_SUCCESS)
+ {
+ log_log(LOG_DEBUG,"<== do_ssl_options: Setting of LDAP_OPT_X_TLS_CIPHER_SUITE failed");
+ return LDAP_OPERATIONS_ERROR;
+ }
+ }
+ if (nslcd_cfg->ldc_tls_cert != NULL)
+ {
+ if (ldap_set_option(NULL,LDAP_OPT_X_TLS_CERTFILE,
+ nslcd_cfg->ldc_tls_cert)!=LDAP_SUCCESS)
+ {
+ log_log(LOG_DEBUG,"<== do_ssl_options: Setting of LDAP_OPT_X_TLS_CERTFILE failed");
+ return LDAP_OPERATIONS_ERROR;
+ }
+ }
+ if (nslcd_cfg->ldc_tls_key != NULL)
+ {
+ if (ldap_set_option(NULL,LDAP_OPT_X_TLS_KEYFILE,
+ nslcd_cfg->ldc_tls_key)!=LDAP_SUCCESS)
+ {
+ log_log(LOG_DEBUG,"<== do_ssl_options: Setting of LDAP_OPT_X_TLS_KEYFILE failed");
+ return LDAP_OPERATIONS_ERROR;
+ }
+ }
+ log_log(LOG_DEBUG,"<== do_ssl_options");
return LDAP_SUCCESS;
}
#endif
@@ -939,7 +1009,6 @@ do_start_tls (struct ldap_session * session)
static enum nss_status
do_open (void)
{
- struct ldap_config *cfg;
int usesasl;
char *bindarg;
enum nss_status stat;
@@ -971,8 +1040,6 @@ do_open (void)
return NSS_STATUS_SUCCESS;
}
- cfg = nslcd_cfg;
-
#if LDAP_SET_REBIND_PROC_ARGS == 3
ldap_set_rebind_proc (__session.ls_conn, do_rebind, NULL);
#elif LDAP_SET_REBIND_PROC_ARGS == 2
@@ -980,12 +1047,12 @@ do_open (void)
#endif
ldap_set_option (__session.ls_conn, LDAP_OPT_PROTOCOL_VERSION,
- &cfg->ldc_version);
+ &nslcd_cfg->ldc_version);
- ldap_set_option (__session.ls_conn, LDAP_OPT_DEREF, &cfg->ldc_deref);
+ ldap_set_option (__session.ls_conn, LDAP_OPT_DEREF, &nslcd_cfg->ldc_deref);
ldap_set_option (__session.ls_conn, LDAP_OPT_TIMELIMIT,
- &cfg->ldc_timelimit);
+ &nslcd_cfg->ldc_timelimit);
#ifdef LDAP_X_OPT_CONNECT_TIMEOUT
/*
@@ -993,28 +1060,28 @@ do_open (void)
* the TCP connect timeout. For want of a better value,
* we use the bind_timelimit to control this.
*/
- timeout = cfg->ldc_bind_timelimit * 1000;
+ timeout = nslcd_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_sec = nslcd_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);
+ nslcd_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);
+ nslcd_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)
+ if (nslcd_cfg->ldc_ssl_on == SSL_START_TLS)
{
int version;
@@ -1031,7 +1098,7 @@ do_open (void)
}
/* set up SSL context */
- if (do_ssl_options (cfg) != LDAP_SUCCESS)
+ if (do_ssl_options()!=LDAP_SUCCESS)
{
do_close ();
log_log(LOG_DEBUG,"<== do_open (SSL setup failed)");
@@ -1056,11 +1123,11 @@ do_open (void)
/*
* If SSL is desired, then enable it.
*/
- if (cfg->ldc_ssl_on == SSL_LDAPS)
+ if (nslcd_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) !=
+ if (ldap_set_option(__session.ls_conn, LDAP_OPT_X_TLS, &tls) !=
LDAP_SUCCESS)
{
do_close ();
@@ -1069,7 +1136,7 @@ do_open (void)
}
/* set up SSL context */
- if (do_ssl_options (cfg) != LDAP_SUCCESS)
+ if (do_ssl_options()!=LDAP_SUCCESS)
{
do_close ();
log_log(LOG_DEBUG,"<== do_open (SSL setup failed)");
@@ -1103,35 +1170,34 @@ do_open (void)
* Thanks to Doug Nazar <nazard@dragoninc.on.ca> for this
* patch.
*/
- if (geteuid() == 0 && cfg->ldc_rootbinddn != NULL)
+ if (geteuid() == 0 && nslcd_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;
+ usesasl = nslcd_cfg->ldc_rootusesasl;
+ bindarg = nslcd_cfg->ldc_rootusesasl ? nslcd_cfg->ldc_rootsaslid : nslcd_cfg->ldc_rootbindpw;
#else
usesasl = 0;
- bindarg = cfg->ldc_rootbindpw;
+ bindarg = nslcd_cfg->ldc_rootbindpw;
#endif
rc = do_bind (__session.ls_conn,
- cfg->ldc_bind_timelimit,
- cfg->ldc_rootbinddn, bindarg, usesasl);
+ nslcd_cfg->ldc_bind_timelimit,
+ nslcd_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;
+ usesasl = nslcd_cfg->ldc_usesasl;
+ bindarg = nslcd_cfg->ldc_usesasl ? nslcd_cfg->ldc_saslid : nslcd_cfg->ldc_bindpw;
#else
usesasl = 0;
- bindarg = cfg->ldc_bindpw;
+ bindarg = nslcd_cfg->ldc_bindpw;
#endif
rc = do_bind (__session.ls_conn,
- cfg->ldc_bind_timelimit,
- cfg->ldc_binddn,
- cfg->ldc_bindpw, usesasl);
+ nslcd_cfg->ldc_bind_timelimit,
+ nslcd_cfg->ldc_binddn,
+ nslcd_cfg->ldc_bindpw, usesasl);
}
if (rc != LDAP_SUCCESS)
@@ -1139,7 +1205,7 @@ do_open (void)
/* 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],
+ nslcd_cfg->ldc_uris[__session.ls_current_uri],
ldap_err2string (rc));
stat = do_map_error (rc);
do_close ();
@@ -1157,102 +1223,6 @@ do_open (void)
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;
-
- log_log(LOG_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)
- {
- log_log(LOG_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)
- {
- log_log(LOG_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)
- {
- log_log(LOG_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)
- {
- log_log(LOG_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)
- {
- log_log(LOG_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)
- {
- log_log(LOG_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)
- {
- log_log(LOG_DEBUG,"<== do_ssl_options: Setting of LDAP_OPT_X_TLS_KEYFILE failed");
- return LDAP_OPERATIONS_ERROR;
- }
- }
-
- log_log(LOG_DEBUG,"<== do_ssl_options");
-
- return LDAP_SUCCESS;
-}
-#endif
-
/*
* This function initializes an enumeration context, acquiring
* the global mutex.
@@ -3165,12 +3135,12 @@ _nss_ldap_map_get (enum ldap_map_selector sel,
NSS_LDAP_DATUM_ZERO (&val);
- stat = _nss_ldap_db_get (map, NSS_LDAP_DB_NORMALIZE_CASE, &key, &val);
+ stat = dict_get (map, NSS_LDAP_DB_NORMALIZE_CASE, &key, &val);
if (stat == NSS_STATUS_NOTFOUND && sel != LM_NONE)
{
map = nslcd_cfg->ldc_maps[LM_NONE][type];
assert (map != NULL);
- stat = _nss_ldap_db_get (map, NSS_LDAP_DB_NORMALIZE_CASE, &key, &val);
+ stat = dict_get (map, NSS_LDAP_DB_NORMALIZE_CASE, &key, &val);
}
if (stat == NSS_STATUS_SUCCESS)
diff --git a/nslcd/util.c b/nslcd/util.c
index 182c822..f067160 100644
--- a/nslcd/util.c
+++ b/nslcd/util.c
@@ -56,91 +56,6 @@
#include "log.h"
#include "cfg.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"
-
-/*
- * 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 )
-
-/*
- * 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;
@@ -159,7 +74,7 @@ dn2uid_cache_put (const char *dn, const char *uid)
if (__cache == NULL)
{
- __cache = (void *)do_alloc_dictionary();
+ __cache = (void *)dict_new();
if (__cache == NULL)
{
cache_unlock ();
@@ -172,7 +87,7 @@ dn2uid_cache_put (const char *dn, const char *uid)
val.data = (void *) uid;
val.size = strlen (uid);
- status = _nss_ldap_db_put (__cache, 0, &key, &val);
+ status = dict_put (__cache, 0, &key, &val);
cache_unlock ();
@@ -196,7 +111,7 @@ dn2uid_cache_get (const char *dn, char **uid, char **buffer, size_t * buflen)
key.data = (void *) dn;
key.size = strlen (dn);
- status = _nss_ldap_db_get (__cache, 0, &key, &val);
+ status = dict_get (__cache, 0, &key, &val);
if (status != NSS_STATUS_SUCCESS)
{
cache_unlock ();
@@ -268,131 +183,6 @@ _nss_ldap_dn2uid (const char *dn, char **uid, char **buffer, size_t * buflen,
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,
@@ -505,922 +295,128 @@ do_getrdnvalue (const char *dn,
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
-_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 retv;
-
- 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;
-
- retv = _nss_ldap_db_put (*map, NSS_LDAP_DB_NORMALIZE_CASE, &key, &val);
- if (retv == 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];
-
- retv = _nss_ldap_db_put (*map, NSS_LDAP_DB_NORMALIZE_CASE, &val, &key);
- }
-
- return retv;
-}
-
-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;
-
- log_log(LOG_DEBUG,"==> _nss_ldap_add_uri");
-
- for (i = 0; result->ldc_uris[i] != NULL; i++)
- ;
-
- if (i == NSS_LDAP_CONFIG_URI_MAX)
- {
- log_log(LOG_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;
-
- log_log(LOG_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)
+_nss_ldap_getrdnvalue (LDAPMessage * entry,
+ const char *rdntype,
+ char **rval, 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;
- }
+ char *dn;
+ enum nss_status status;
- fp = fopen (NSS_LDAP_PATH_CONF, "r");
- if (fp == NULL)
+ dn = _nss_ldap_get_dn (entry);
+ if (dn == NULL)
{
- return NSS_STATUS_UNAVAIL;
+ return NSS_STATUS_NOTFOUND;
}
- if (fstat (fileno (fp), &statbuf) == 0)
- result->ldc_mtime = statbuf.st_mtime;
- else
- result->ldc_mtime = 0;
+ 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 */
- while (fgets (b, sizeof (b), fp) != NULL)
+ /*
+ * 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 *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';
+ char **vals;
- if (*buflen < (size_t) (len + 1))
- {
- status = NSS_STATUS_TRYAGAIN;
- break;
- }
+ vals = _nss_ldap_get_values (entry, rdntype);
- 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 (vals != NULL)
{
- if (!strcasecmp (v, "on")
- || !strcasecmp (v, "yes")
- || !strcasecmp (v, "true"))
+ int rdnlen = strlen (*vals);
+ if (*buflen > rdnlen)
{
- result->ldc_flags |= NSS_LDAP_FLAGS_PAGED_RESULTS;
+ char *rdnvalue = *buffer;
+ strncpy (rdnvalue, *vals, rdnlen);
+ rdnvalue[rdnlen] = '\0';
+ *buffer += rdnlen + 1;
+ *buflen -= rdnlen + 1;
+ *rval = rdnvalue;
+ status = NSS_STATUS_SUCCESS;
}
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;
+ status = NSS_STATUS_TRYAGAIN;
}
+ ldap_value_free (vals);
}
-
- 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;
- }
- }
+ return status;
+}
- if (result->ldc_port == 0)
+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)
{
- if (result->ldc_ssl_on == SSL_LDAPS)
- {
- result->ldc_port = LDAPS_PORT;
- }
- else
+ for (i=0;exploded_rdn[i]!=NULL;i++)
+ {
+ /* if the values begins with rndava */
+ if (strncasecmp(exploded_rdn[i],rdnava,rdnavalen)==0)
{
- result->ldc_port = LDAP_PORT;
+ /* FIXME: handle case where WRITE fails */
+ WRITE_STRING(fp,exploded_rdn[i]+rdnavalen);
+ status=0;
+ break;
}
+ }
+ ldap_value_free(exploded_rdn);
}
-
- if (result->ldc_uris[0] == NULL)
+ 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)
{
- status = NSS_STATUS_NOTFOUND;
+ /* write the first entry */
+ WRITE_STRING(fp,vals[0]);
+ status=NSS_STATUS_SUCCESS;
+ ldap_value_free(vals);
+ status=0;
}
-
+ }
return status;
}
@@ -1463,28 +459,17 @@ int _nss_ldap_escape_string(const char *src,char *buffer,size_t buflen)
return 0;
}
-/* 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_new(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;
-
+ dict = malloc(sizeof(struct ldap_dictionary));
+ if (dict==NULL)
+ {
+ return NULL;
+ }
+ NSS_LDAP_DATUM_ZERO(&dict->key);
+ NSS_LDAP_DATUM_ZERO(&dict->value);
+ dict->next=NULL;
return dict;
}
@@ -1531,103 +516,74 @@ do_dup_datum (unsigned flags, struct ldap_datum * dst, const struct ldap_datum *
return NSS_STATUS_SUCCESS;
}
-enum nss_status
-_nss_ldap_db_get (void *db,
- unsigned flags,
- const struct ldap_datum * key,
- struct ldap_datum * value)
+enum nss_status dict_get(
+ struct ldap_dictionary *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;
- }
+ for (p=db;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)
+enum nss_status dict_put(
+ struct ldap_dictionary *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);
+ assert(key!=NULL);
+ assert(key->data!=NULL);
- if (dict->key.data == NULL)
- {
- /* uninitialized */
- q = dict;
- p = 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);
+ {
+ p=do_find_last(dict);
+ assert(p!=NULL);
+ assert(p->next==NULL);
+ q=dict_new();
+ if (q==NULL)
return NSS_STATUS_TRYAGAIN;
- }
-
- if (p != NULL)
- p->next = q;
-
- return NSS_STATUS_SUCCESS;
-}
-
-enum nss_status _nss_ldap_validateconfig (struct ldap_config *config)
-{
- struct stat statbuf;
+ }
- if (config == NULL)
- {
- return NSS_STATUS_UNAVAIL;
- }
+ if (do_dup_datum(flags,&q->key,key)!=NSS_STATUS_SUCCESS)
+ {
+ do_free_dictionary(q);
+ return NSS_STATUS_TRYAGAIN;
+ }
- if (config->ldc_mtime == 0)
- {
- return NSS_STATUS_SUCCESS;
- }
+ if (do_dup_datum(flags,&q->value,value)!=NSS_STATUS_SUCCESS)
+ {
+ do_free_dictionary(q);
+ return NSS_STATUS_TRYAGAIN;
+ }
- if (stat (NSS_LDAP_PATH_CONF, &statbuf) == 0)
- {
- return (statbuf.st_mtime > config->ldc_mtime) ? NSS_STATUS_TRYAGAIN : NSS_STATUS_SUCCESS;
- }
+ if (p!=NULL)
+ p->next=q;
return NSS_STATUS_SUCCESS;
}
diff --git a/nslcd/util.h b/nslcd/util.h
index 44698d9..eacc7da 100644
--- a/nslcd/util.h
+++ b/nslcd/util.h
@@ -44,22 +44,14 @@ enum nss_status _nss_ldap_dn2uid (const char *dn,
int *pIsNestedGroup, LDAPMessage ** pRes);
-#define NSS_LDAP_CONFIG_BUFSIZ 4096
-
-/*
- * 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
-
/*
* Escape '*' in a string for use as a filter
*/
int _nss_ldap_escape_string(const char *str,char *buf,size_t buflen);
+/* Dictionary functions. */
+
struct ldap_datum
{
void *data;
@@ -73,17 +65,24 @@ struct ldap_datum
#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);
-
-enum nss_status
-_nss_ldap_add_uri (struct ldap_config *result, const char *uri,
- char **buffer, size_t *buflen);
+struct ldap_dictionary
+{
+ struct ldap_datum key;
+ struct ldap_datum value;
+ struct ldap_dictionary *next;
+};
+
+struct ldap_dictionary *dict_new(void);
+enum nss_status dict_put(struct ldap_dictionary *db,
+ unsigned flags,
+ const struct ldap_datum *key,
+ const struct ldap_datum *value);
+enum nss_status dict_get(struct ldap_dictionary *db,
+ unsigned flags,
+ const struct ldap_datum *key,
+ struct ldap_datum *value);
+
+
+
#endif /* _LDAP_NSS_LDAP_UTIL_H */