diff options
author | Arthur de Jong <arthur@arthurdejong.org> | 2007-01-17 16:03:11 +0000 |
---|---|---|
committer | Arthur de Jong <arthur@arthurdejong.org> | 2007-01-17 16:03:11 +0000 |
commit | d2296ccd7c8bfdfffe4dc99c4c4db32eaae4c60b (patch) | |
tree | e35d6b53cc0b53c7425f8bf8f3923c28fc34562d /nslcd/util.c | |
parent | c026629eedf04f9d3579180980bb6bfa6759d15b (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.c | 1364 |
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; } |