summaryrefslogtreecommitdiff
path: root/nslcd/util.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/util.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/util.c')
-rw-r--r--nslcd/util.c1364
1 files changed, 160 insertions, 1204 deletions
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;
}