summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArthur de Jong <arthur@arthurdejong.org>2008-07-20 08:05:54 +0000
committerArthur de Jong <arthur@arthurdejong.org>2008-07-20 08:05:54 +0000
commitf26e49b5d58f4f8268bdb25980cbc11528383bd1 (patch)
treee42e52b56ee3b3250e5a3230f36515090f5db93d
parente963b7913712bc5c7e954deaf94fde4709534a33 (diff)
implement looking up search base in DSE of LDAP server
git-svn-id: http://arthurdejong.org/svn/nss-pam-ldapd/nss-ldapd@775 ef36b2f9-881f-0410-afb5-c4e39611909c
-rw-r--r--man/nss-ldapd.conf.5.xml8
-rw-r--r--nslcd/cfg.c53
2 files changed, 60 insertions, 1 deletions
diff --git a/man/nss-ldapd.conf.5.xml b/man/nss-ldapd.conf.5.xml
index e90317c..2fd9f11 100644
--- a/man/nss-ldapd.conf.5.xml
+++ b/man/nss-ldapd.conf.5.xml
@@ -293,7 +293,13 @@
<para>
If, instead of a <acronym>DN</acronym>, the value
<emphasis remap="I">DOMAIN</emphasis> is specified, the host's
- <acronym>DNS</acronym> domain is used to construct a basedn.
+ <acronym>DNS</acronym> domain is used to construct a search base.
+ </para>
+ <para>
+ If this value is not defined an attempt is made to look it up
+ in the configured <acronym>LDAP</acronym> server. Note that if the
+ <acronym>LDAP</acronym> server is unavailable during start-up
+ <command>nslcd</command> will not start.
</para>
</listitem>
</varlistentry>
diff --git a/nslcd/cfg.c b/nslcd/cfg.c
index a8b05ef..6cd7003 100644
--- a/nslcd/cfg.c
+++ b/nslcd/cfg.c
@@ -896,6 +896,49 @@ static void cfg_read(const char *filename,struct ldap_config *cfg)
fclose(fp);
}
+static void get_base_from_dse(struct ldap_config *cfg)
+{
+ MYLDAP_SESSION *session;
+ MYLDAP_SEARCH *search;
+ MYLDAP_ENTRY *entry;
+ const char *attrs[] = { "+", NULL };
+ int i;
+ int rc;
+ const char **values;
+ /* initialize session */
+ session=myldap_create_session();
+ assert(session!=NULL);
+ /* perform search */
+ search=myldap_search(session,"",LDAP_SCOPE_BASE,"(objectClass=*)",attrs);
+ if (search==NULL)
+ {
+ myldap_session_close(session);
+ return;
+ }
+ /* go over results */
+ for (i=0;(entry=myldap_get_entry(search,&rc))!=NULL;i++)
+ {
+ /* get defaultNamingContext */
+ values=myldap_get_values(entry,"defaultNamingContext");
+ if ((values!=NULL)&&(values[0]!=NULL))
+ {
+ cfg->ldc_base=xstrdup(values[0]);
+ log_log(LOG_DEBUG,"get_basedn_from_dse(): found attribute defaultNamingContext with value %s",values[0]);
+ break;
+ }
+ /* get namingContexts */
+ values=myldap_get_values(entry,"namingContexts");
+ if ((values!=NULL)&&(values[0]!=NULL))
+ {
+ cfg->ldc_base=xstrdup(values[0]);
+ log_log(LOG_DEBUG,"get_basedn_from_dse(): found attribute namingContexts with value %s",values[0]);
+ break;
+ }
+ }
+ /* clean up */
+ myldap_session_close(session);
+}
+
void cfg_init(const char *fname)
{
#ifdef LDAP_OPT_X_TLS
@@ -937,4 +980,14 @@ void cfg_init(const char *fname)
}
/* TODO: check that if some tls options are set the ssl option should be set to on (just warn) */
#endif /* LDAP_OPT_X_TLS */
+ /* if basedn is not yet set, get if from the DSE */
+ if (nslcd_cfg->ldc_base==NULL)
+ get_base_from_dse(nslcd_cfg);
+ /* TODO: handle the case gracefully when no LDAP server is available yet */
+ /* see if we have a valid basedn */
+ if ((nslcd_cfg->ldc_base==NULL)||(nslcd_cfg->ldc_base[0]=='\0'))
+ {
+ log_log(LOG_ERR,"no base defined in config and couldn't get one from server");
+ exit(EXIT_FAILURE);
+ }
}