summaryrefslogtreecommitdiff
path: root/nslcd/cfg.c
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 /nslcd/cfg.c
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
Diffstat (limited to 'nslcd/cfg.c')
-rw-r--r--nslcd/cfg.c1000
1 files changed, 984 insertions, 16 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;
+}