Arthur de Jong

Open Source / Free Software developer

summaryrefslogtreecommitdiffstats
path: root/nslcd
diff options
context:
space:
mode:
Diffstat (limited to 'nslcd')
-rw-r--r--nslcd/attmap.c128
-rw-r--r--nslcd/attmap.h3
-rw-r--r--nslcd/cfg.c1205
-rw-r--r--nslcd/cfg.h94
-rw-r--r--nslcd/ldap-nss.c4
-rw-r--r--nslcd/ldap-schema.h16
-rw-r--r--nslcd/nslcd.c7
7 files changed, 670 insertions, 787 deletions
diff --git a/nslcd/attmap.c b/nslcd/attmap.c
index 4029d43..bec4a51 100644
--- a/nslcd/attmap.c
+++ b/nslcd/attmap.c
@@ -177,92 +177,92 @@ const char *attmap_shadow_shadowInactive = "shadowInactive";
const char *attmap_shadow_shadowExpire = "shadowExpire";
const char *attmap_shadow_shadowFlag = "shadowFlag";
-const char **attmap_get_var(const char *name)
+const char **attmap_get_var(enum ldap_map_selector map,const char *name)
{
- if (strncasecmp(name,"alias.",6)==0)
+ if (map==LM_ALIASES)
{
- if (strcasecmp(name+6,"objectClass")==0) return &attmap_alias_objectClass;
- if (strcasecmp(name+6,"cn")==0) return &attmap_alias_cn;
- if (strcasecmp(name+6,"rfc822MailMember")==0) return &attmap_alias_rfc822MailMember;
+ if (strcasecmp(name,"objectClass")==0) return &attmap_alias_objectClass;
+ if (strcasecmp(name,"cn")==0) return &attmap_alias_cn;
+ if (strcasecmp(name,"rfc822MailMember")==0) return &attmap_alias_rfc822MailMember;
}
- else if (strncasecmp(name,"ether.",6)==0)
+ else if (map==LM_ETHERS)
{
- if (strcasecmp(name+6,"objectClass")==0) return &attmap_ether_objectClass;
- if (strcasecmp(name+6,"cn")==0) return &attmap_ether_cn;
- if (strcasecmp(name+6,"macAddress")==0) return &attmap_ether_macAddress;
+ if (strcasecmp(name,"objectClass")==0) return &attmap_ether_objectClass;
+ if (strcasecmp(name,"cn")==0) return &attmap_ether_cn;
+ if (strcasecmp(name,"macAddress")==0) return &attmap_ether_macAddress;
}
- else if (strncasecmp(name,"group.",6)==0)
+ else if (map==LM_GROUP)
{
- if (strcasecmp(name+6,"objectClass")==0) return &attmap_group_objectClass;
- if (strcasecmp(name+6,"cn")==0) return &attmap_group_cn;
- if (strcasecmp(name+6,"userPassword")==0) return &attmap_group_userPassword;
- if (strcasecmp(name+6,"gidNumber")==0) return &attmap_group_gidNumber;
- if (strcasecmp(name+6,"memberUid")==0) return &attmap_group_memberUid;
- if (strcasecmp(name+6,"uniqueMember")==0) return &attmap_group_uniqueMember;
- if (strcasecmp(name+6,"memberOf")==0) return &attmap_group_memberOf;
+ if (strcasecmp(name,"objectClass")==0) return &attmap_group_objectClass;
+ if (strcasecmp(name,"cn")==0) return &attmap_group_cn;
+ if (strcasecmp(name,"userPassword")==0) return &attmap_group_userPassword;
+ if (strcasecmp(name,"gidNumber")==0) return &attmap_group_gidNumber;
+ if (strcasecmp(name,"memberUid")==0) return &attmap_group_memberUid;
+ if (strcasecmp(name,"uniqueMember")==0) return &attmap_group_uniqueMember;
+ if (strcasecmp(name,"memberOf")==0) return &attmap_group_memberOf;
}
- else if (strncasecmp(name,"host.",5)==0)
+ else if (map==LM_HOSTS)
{
- if (strcasecmp(name+5,"objectClass")==0) return &attmap_host_objectClass;
- if (strcasecmp(name+5,"cn")==0) return &attmap_host_cn;
- if (strcasecmp(name+5,"ipHostNumber")==0) return &attmap_host_ipHostNumber;
+ if (strcasecmp(name,"objectClass")==0) return &attmap_host_objectClass;
+ if (strcasecmp(name,"cn")==0) return &attmap_host_cn;
+ if (strcasecmp(name,"ipHostNumber")==0) return &attmap_host_ipHostNumber;
}
- else if (strncasecmp(name,"netgroup.",9)==0)
+ else if (map==LM_NETGROUP)
{
- if (strcasecmp(name+9,"objectClass")==0) return &attmap_netgroup_objectClass;
- if (strcasecmp(name+9,"cn")==0) return &attmap_netgroup_cn;
- if (strcasecmp(name+9,"nisNetgroupTriple")==0) return &attmap_netgroup_nisNetgroupTriple;
- if (strcasecmp(name+9,"memberNisNetgroup")==0) return &attmap_netgroup_memberNisNetgroup;
+ if (strcasecmp(name,"objectClass")==0) return &attmap_netgroup_objectClass;
+ if (strcasecmp(name,"cn")==0) return &attmap_netgroup_cn;
+ if (strcasecmp(name,"nisNetgroupTriple")==0) return &attmap_netgroup_nisNetgroupTriple;
+ if (strcasecmp(name,"memberNisNetgroup")==0) return &attmap_netgroup_memberNisNetgroup;
}
- else if (strncasecmp(name,"network.",8)==0)
+ else if (map==LM_NETWORKS)
{
- if (strcasecmp(name+8,"objectClass")==0) return &attmap_network_objectClass;
- if (strcasecmp(name+8,"cn")==0) return &attmap_network_cn;
- if (strcasecmp(name+8,"ipNetworkNumber")==0) return &attmap_network_ipNetworkNumber;
+ if (strcasecmp(name,"objectClass")==0) return &attmap_network_objectClass;
+ if (strcasecmp(name,"cn")==0) return &attmap_network_cn;
+ if (strcasecmp(name,"ipNetworkNumber")==0) return &attmap_network_ipNetworkNumber;
}
- else if (strncasecmp(name,"passwd.",7)==0)
+ else if (map==LM_PASSWD)
{
- if (strcasecmp(name+7,"objectClass")==0) return &attmap_passwd_objectClass;
- if (strcasecmp(name+7,"uid")==0) return &attmap_passwd_uid;
- if (strcasecmp(name+7,"userPassword")==0) return &attmap_passwd_userPassword;
- if (strcasecmp(name+7,"uidNumber")==0) return &attmap_passwd_uidNumber;
- if (strcasecmp(name+7,"gidNumber")==0) return &attmap_passwd_gidNumber;
- if (strcasecmp(name+7,"gecos")==0) return &attmap_passwd_gecos;
- if (strcasecmp(name+7,"cn")==0) return &attmap_passwd_cn;
- if (strcasecmp(name+7,"homeDirectory")==0) return &attmap_passwd_homeDirectory;
- if (strcasecmp(name+7,"loginShell")==0) return &attmap_passwd_loginShell;
+ if (strcasecmp(name,"objectClass")==0) return &attmap_passwd_objectClass;
+ if (strcasecmp(name,"uid")==0) return &attmap_passwd_uid;
+ if (strcasecmp(name,"userPassword")==0) return &attmap_passwd_userPassword;
+ if (strcasecmp(name,"uidNumber")==0) return &attmap_passwd_uidNumber;
+ if (strcasecmp(name,"gidNumber")==0) return &attmap_passwd_gidNumber;
+ if (strcasecmp(name,"gecos")==0) return &attmap_passwd_gecos;
+ if (strcasecmp(name,"cn")==0) return &attmap_passwd_cn;
+ if (strcasecmp(name,"homeDirectory")==0) return &attmap_passwd_homeDirectory;
+ if (strcasecmp(name,"loginShell")==0) return &attmap_passwd_loginShell;
}
- else if (strncasecmp(name,"protocol.",9)==0)
+ else if (map==LM_PROTOCOLS)
{
- if (strcasecmp(name+9,"objectClass")==0) return &attmap_protocol_objectClass;
- if (strcasecmp(name+9,"cn")==0) return &attmap_protocol_cn;
- if (strcasecmp(name+9,"ipProtocolNumber")==0) return &attmap_protocol_ipProtocolNumber;
+ if (strcasecmp(name,"objectClass")==0) return &attmap_protocol_objectClass;
+ if (strcasecmp(name,"cn")==0) return &attmap_protocol_cn;
+ if (strcasecmp(name,"ipProtocolNumber")==0) return &attmap_protocol_ipProtocolNumber;
}
- else if (strncasecmp(name,"rpc.",4)==0)
+ else if (map==LM_RPC)
{
- if (strcasecmp(name+9,"objectClass")==0) return &attmap_rpc_objectClass;
- if (strcasecmp(name+9,"cn")==0) return &attmap_rpc_cn;
- if (strcasecmp(name+9,"oncRpcNumber")==0) return &attmap_rpc_oncRpcNumber;
+ if (strcasecmp(name,"objectClass")==0) return &attmap_rpc_objectClass;
+ if (strcasecmp(name,"cn")==0) return &attmap_rpc_cn;
+ if (strcasecmp(name,"oncRpcNumber")==0) return &attmap_rpc_oncRpcNumber;
}
- else if (strncasecmp(name,"service.",8)==0)
+ else if (map==LM_SERVICES)
{
- if (strcasecmp(name+8,"objectClass")==0) return &attmap_service_objectClass;
- if (strcasecmp(name+8,"cn")==0) return &attmap_service_cn;
- if (strcasecmp(name+8,"ipServicePort")==0) return &attmap_service_ipServicePort;
- if (strcasecmp(name+8,"ipServiceProtocol")==0) return &attmap_service_ipServiceProtocol;
+ if (strcasecmp(name,"objectClass")==0) return &attmap_service_objectClass;
+ if (strcasecmp(name,"cn")==0) return &attmap_service_cn;
+ if (strcasecmp(name,"ipServicePort")==0) return &attmap_service_ipServicePort;
+ if (strcasecmp(name,"ipServiceProtocol")==0) return &attmap_service_ipServiceProtocol;
}
- else if (strncasecmp(name,"shadow.",7)==0)
+ else if (map==LM_SHADOW)
{
- if (strcasecmp(name+7,"objectClass")==0) return &attmap_shadow_objectClass;
- if (strcasecmp(name+7,"uid")==0) return &attmap_shadow_uid;
- if (strcasecmp(name+7,"userPassword")==0) return &attmap_shadow_userPassword;
- if (strcasecmp(name+7,"shadowLastChange")==0) return &attmap_shadow_shadowLastChange;
- if (strcasecmp(name+7,"shadowMin")==0) return &attmap_shadow_shadowMin;
- if (strcasecmp(name+7,"shadowMax")==0) return &attmap_shadow_shadowMax;
- if (strcasecmp(name+7,"shadowWarning")==0) return &attmap_shadow_shadowWarning;
- if (strcasecmp(name+7,"shadowInactive")==0) return &attmap_shadow_shadowInactive;
- if (strcasecmp(name+7,"shadowExpire")==0) return &attmap_shadow_shadowExpire;
- if (strcasecmp(name+7,"shadowFlag")==0) return &attmap_shadow_shadowFlag;
+ if (strcasecmp(name,"objectClass")==0) return &attmap_shadow_objectClass;
+ if (strcasecmp(name,"uid")==0) return &attmap_shadow_uid;
+ if (strcasecmp(name,"userPassword")==0) return &attmap_shadow_userPassword;
+ if (strcasecmp(name,"shadowLastChange")==0) return &attmap_shadow_shadowLastChange;
+ if (strcasecmp(name,"shadowMin")==0) return &attmap_shadow_shadowMin;
+ if (strcasecmp(name,"shadowMax")==0) return &attmap_shadow_shadowMax;
+ if (strcasecmp(name,"shadowWarning")==0) return &attmap_shadow_shadowWarning;
+ if (strcasecmp(name,"shadowInactive")==0) return &attmap_shadow_shadowInactive;
+ if (strcasecmp(name,"shadowExpire")==0) return &attmap_shadow_shadowExpire;
+ if (strcasecmp(name,"shadowFlag")==0) return &attmap_shadow_shadowFlag;
}
return NULL;
}
diff --git a/nslcd/attmap.h b/nslcd/attmap.h
index acf8341..abb1287 100644
--- a/nslcd/attmap.h
+++ b/nslcd/attmap.h
@@ -23,6 +23,7 @@
#ifndef _ATTMAP_H
#define _ATTMAP_H 1
+#include "ldap-nss.h"
/* What follows is a list of attribute names per database. */
@@ -179,6 +180,6 @@ extern const char *attmap_shadow_shadowFlag;
/* return a reference to the attribute mapping variable for the specified name
the name is the name after the attmap_... variables above with the
underscode replaced by a dot (e.g passwd.homeDirectory) */
-const char **attmap_get_var(const char *name);
+const char **attmap_get_var(enum ldap_map_selector map,const char *name);
#endif /* not _ATTMAP_H */
diff --git a/nslcd/cfg.c b/nslcd/cfg.c
index 8d44725..74cfa9e 100644
--- a/nslcd/cfg.c
+++ b/nslcd/cfg.c
@@ -32,6 +32,7 @@
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
+#include <errno.h>
#include "ldap-nss.h"
#include "util.h"
@@ -53,52 +54,11 @@ struct ldap_config *nslcd_cfg=NULL;
#define LDAP_NSS_MAXSLEEPTIME 64 /* maximum seconds to sleep */
#define LDAP_NSS_MAXCONNTRIES 2 /* reconnect attempts before sleeping */
-#define NSS_LDAP_KEY_MAP "map"
-#define NSS_LDAP_KEY_SCOPE "scope"
-#define NSS_LDAP_KEY_BASE "base"
-#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_DEBUG "debug"
-#define NSS_LDAP_KEY_PAGESIZE "pagesize"
-
-/* 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"
+/* the maximum line length in the configuration file */
+#define MAX_LINE_LENGTH 4096
-#define NSS_LDAP_KEY_SCHEMA "nss_schema"
-#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
+/* the maximum number of keywords/options on the line */
+#define MAX_LINE_OPTIONS 10
int _nss_ldap_test_config_flag(unsigned int flag)
{
@@ -106,684 +66,611 @@ int _nss_ldap_test_config_flag(unsigned int flag)
(nslcd_cfg->ldc_flags&flag);
}
-static void _nss_ldap_init_config(struct ldap_config *result)
+/* clear the configuration information back to the defaults */
+static void cfg_defaults(struct ldap_config *cfg)
{
-
- 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;
+ int i;
+ memset(cfg,0,sizeof(struct ldap_config));
+ for (i=0;i<(NSS_LDAP_CONFIG_URI_MAX+1);i++)
+ cfg->ldc_uris[i]=NULL;
#ifdef LDAP_VERSION3
- result->ldc_version = LDAP_VERSION3;
+ cfg->ldc_version=LDAP_VERSION3;
#else /* LDAP_VERSION3 */
- result->ldc_version = LDAP_VERSION2;
+ cfg->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_debug = 0;
- result->ldc_pagesize = 0;
+ cfg->ldc_binddn=NULL;
+ cfg->ldc_bindpw=NULL;
+ cfg->ldc_rootbinddn=NULL;
+ cfg->ldc_rootbindpw=NULL;
+ cfg->ldc_saslid=NULL;
+ cfg->ldc_rootsaslid=NULL;
+ cfg->ldc_sasl_secprops=NULL;
+ cfg->ldc_usesasl=0;
+ cfg->ldc_rootusesasl=0;
#ifdef CONFIGURE_KRB5_CCNAME
- result->ldc_krb5_ccname = NULL;
+ cfg->ldc_krb5_ccname=NULL;
#endif /* CONFIGURE_KRB5_CCNAME */
- result->ldc_flags = 0;
-#ifdef RFC2307BIS
- result->ldc_flags |= NSS_LDAP_FLAGS_RFC2307BIS;
-#endif /* RFC2307BIS */
- 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;
+ cfg->ldc_base=NULL;
+ cfg->ldc_scope=LDAP_SCOPE_SUBTREE;
+ cfg->ldc_deref=LDAP_DEREF_NEVER;
+ cfg->ldc_referrals=1;
+ for (i=0;i<LM_NONE;i++)
+ cfg->ldc_sds[i]=NULL;
+ cfg->ldc_timelimit=LDAP_NO_LIMIT;
+ cfg->ldc_bind_timelimit=30;
+ cfg->ldc_reconnect_pol=LP_RECONNECT_HARD_OPEN;
+ cfg->ldc_flags=0;
+ cfg->ldc_idle_timelimit=0;
+ cfg->ldc_ssl_on=SSL_OFF;
+ cfg->ldc_sslpath=NULL;
+ cfg->ldc_tls_checkpeer=-1;
+ cfg->ldc_tls_cacertdir=NULL;
+ cfg->ldc_tls_cacertfile=NULL;
+ cfg->ldc_tls_randfile=NULL;
+ cfg->ldc_tls_ciphers=NULL;
+ cfg->ldc_tls_cert=NULL;
+ cfg->ldc_tls_key=NULL;
+ cfg->ldc_restart=1;
+ cfg->ldc_pagesize=0;
+ cfg->ldc_reconnect_tries=LDAP_NSS_TRIES;
+ cfg->ldc_reconnect_sleeptime=LDAP_NSS_SLEEPTIME;
+ cfg->ldc_reconnect_maxsleeptime=LDAP_NSS_MAXSLEEPTIME;
+ cfg->ldc_reconnect_maxconntries=LDAP_NSS_MAXCONNTRIES;
+ cfg->ldc_debug=0;
+ cfg->ldc_password_type=LU_RFC2307_USERPASSWORD;
+ cfg->ldc_shadow_type=LS_RFC2307_SHADOW;
}
-static enum nss_status
-_nss_ldap_add_uri (struct ldap_config *result, const char *uri,
- char **buffer, size_t *buflen)
+/* simple strdup wrapper */
+static char *xstrdup(const char *s)
{
- /* 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");
+ char *tmp;
+ if (s==NULL)
+ {
+ log_log(LOG_CRIT,"xstrdup() called with NULL");
+ exit(EXIT_FAILURE);
+ }
+ tmp=strdup(s);
+ if (tmp==NULL)
+ {
+ log_log(LOG_CRIT,"strdup() failed to allocate memory");
+ exit(EXIT_FAILURE);
+ }
+ return tmp;
+}
- for (i = 0; result->ldc_uris[i] != NULL; i++)
+/* add a single URI to the list of URIs in the configuration */
+static void add_uri(const char *filename,int lnr,
+ struct ldap_config *cfg,const char *uri)
+{
+ int i;
+ log_log(LOG_DEBUG,"add_uri(%s)",uri);
+ /* find the place where to insert the URI */
+ for (i=0;cfg->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;
+ /* check for room */
+ if (i>=NSS_LDAP_CONFIG_URI_MAX)
+ {
+ log_log(LOG_ERR,"%s:%d: maximum number of URIs exceeded",filename,lnr);
+ exit(EXIT_FAILURE);
+ }
+ /* append URI to list */
+ cfg->ldc_uris[i]=xstrdup(uri);
+ cfg->ldc_uris[i+1]=NULL;
}
-static enum nss_status
-do_add_uris (struct ldap_config *result, char *uris,
- char **buffer, size_t *buflen)
+static int parse_boolean(const char *filename,int lnr,const char *value)
{
- /* 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;
- }
+ if ( (strcasecmp(value,"on")==0) ||
+ (strcasecmp(value,"yes")==0) ||
+ (strcasecmp(value,"true")==0) ||
+ (strcasecmp(value,"1")==0) )
+ return 1;
+ else if ( (strcasecmp(value,"off")==0) ||
+ (strcasecmp(value,"no")==0) ||
+ (strcasecmp(value,"false")==0) ||
+ (strcasecmp(value,"0")==0) )
+ return 0;
+ else
+ {
+ log_log(LOG_ERR,"%s:%d: not a boolean argument: '%s'",filename,lnr,value);
+ exit(EXIT_FAILURE);
+ }
+}
- return status;
+static int parse_scope(const char *filename,int lnr,const char *value)
+{
+ if ( (strcasecmp(value,"sub")==0) || (strcasecmp(value,"subtree")==0) )
+ return LDAP_SCOPE_SUBTREE;
+ else if ( (strcasecmp(value,"one")==0) || (strcasecmp(value,"onelevel")==0) )
+ return LDAP_SCOPE_ONELEVEL;
+ else if (strcasecmp(value,"base")==0)
+ return LDAP_SCOPE_BASE;
+ else
+ {
+ log_log(LOG_ERR,"%s:%d: not a scope argument: '%s'",filename,lnr,value);
+ exit(EXIT_FAILURE);
+ }
}
-static enum ldap_map_selector _nss_ldap_str2selector(const char *key)
+static enum ldap_map_selector parse_map(const char *filename,int lnr,const char *value)
{
- 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_aliases))
- sel = LM_ALIASES;
- else if (!strcasecmp (key, MP_netgroup))
- sel = LM_NETGROUP;
+ /* TODO: merge this code with attmap_get_var() */
+ if ( (strcasecmp(value,"alias")==0) || (strcasecmp(value,"aliases")==0) )
+ return LM_ALIASES;
+ else if ( (strcasecmp(value,"ether")==0) || (strcasecmp(value,"ethers")==0) )
+ return LM_ETHERS;
+ else if (strcasecmp(value,"group")==0)
+ return LM_GROUP;
+ else if ( (strcasecmp(value,"host")==0) || (strcasecmp(value,"hosts")==0) )
+ return LM_HOSTS;
+ else if (strcasecmp(value,"netgroup")==0)
+ return LM_NETGROUP;
+ else if ( (strcasecmp(value,"network")==0) || (strcasecmp(value,"networks")==0) )
+ return LM_NETWORKS;
+ else if (strcasecmp(value,"passwd")==0)
+ return LM_PASSWD;
+ else if ( (strcasecmp(value,"protocol")==0) || (strcasecmp(value,"protocols")==0) )
+ return LM_PROTOCOLS;
+ else if (strcasecmp(value,"rpc")==0)
+ return LM_RPC;
+ else if ( (strcasecmp(value,"service")==0) || (strcasecmp(value,"services")==0) )
+ return LM_SERVICES;
+ else if (strcasecmp(value,"shadow")==0)
+ return LM_SHADOW;
else
- sel = LM_NONE;
- return sel;
+ {
+ log_log(LOG_ERR,"%s:%d: unknown mapping: '%s'",filename,lnr,value);
+ exit(EXIT_FAILURE);
+ }
}
/* this function modifies the statement argument passed */
-static enum nss_status do_parse_map_statement(
- struct ldap_config *cfg,char *statement)
+static void parse_map_statement(const char *filename,int lnr,
+ struct ldap_config *cfg,const char **opts)
{
- char *key,*val;
+ enum ldap_map_selector map;
const char **var;
- key=(char *)statement;
- val=key;
- /* search for the end of the key */
- while (*val!=' '&&*val!='\t')
- val++;
- *(val++)='\0';
- /* search for the end of the value */
- while (*val==' '||*val=='\t')
- val++;
+ /* get the map */
+ map=parse_map(filename,lnr,opts[1]);
/* special handling for some attribute mappings */
- if (strcasecmp(key,"passwd.userPassword")==0)
+ /* TODO: move this stuff to passwd.c or shadow.c or wherever it's used */
+ if ((map==LM_PASSWD)&&(strcasecmp(opts[2],"userPassword")==0))
{
- if (strcasecmp(val,"userPassword")==0)
+ if (strcasecmp(opts[3],"userPassword")==0)
cfg->ldc_password_type=LU_RFC2307_USERPASSWORD;
- else if (strcasecmp (val,"authPassword")==0)
+ else if (strcasecmp(opts[3],"authPassword")==0)
cfg->ldc_password_type=LU_RFC3112_AUTHPASSWORD;
else
cfg->ldc_password_type=LU_OTHER_PASSWORD;
}
- else if (strcasecmp(key,"shadow.shadowLastChange")==0)
+ else if ((map==LM_SHADOW)&&(strcasecmp(opts[2],"shadowLastChange")==0))
{
- if (strcasecmp(val,"shadowLastChange")==0)
+ if (strcasecmp(opts[3],"shadowLastChange")==0)
cfg->ldc_shadow_type=LS_RFC2307_SHADOW;
- else if (strcasecmp (val,"pwdLastSet")==0)
+ else if (strcasecmp(opts[3],"pwdLastSet")==0)
cfg->ldc_shadow_type=LS_AD_SHADOW;
}
- var=attmap_get_var(key);
+ var=attmap_get_var(map,opts[2]);
if (var==NULL)
- /* the used mapping key was unknown */
- return NSS_STATUS_NOTFOUND;
- /* check if the value actually changed */
- if (strcmp(*var,val)!=0)
+ {
+ log_log(LOG_ERR,"%s:%d: unknown attribute to map: '%s'",filename,lnr,opts[2]);
+ exit(EXIT_FAILURE);
+ }
+ /* check if the value will be changed */
+ if (strcmp(*var,opts[3])!=0)
{
/* Note: we have a memory leak here if a single mapping is changed
multiple times in one config (deemed not a problem) */
- *var=strdup(val);
- if (*var==NULL)
- /* memory allocation failed */
- return NSS_STATUS_TRYAGAIN;
+ *var=xstrdup(opts[3]);
}
- 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)
+static void alloc_lsd(struct ldap_service_search_descriptor **lsd)
{
- 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)
+ if (*lsd!=NULL)
+ return;
+ *lsd=(struct ldap_service_search_descriptor *)malloc(sizeof(struct ldap_service_search_descriptor));
+ if (*lsd==NULL)
+ {
+ log_log(LOG_CRIT,"malloc() failed to allocate memory");
+ exit(EXIT_FAILURE);
+ }
+ /* initialize fields */
+ (*lsd)->lsd_base=NULL;
+ (*lsd)->lsd_scope=-1;
+ (*lsd)->lsd_filter=NULL;
+ (*lsd)->lsd_next=NULL;
+}
+
+static void do_setbase(struct ldap_service_search_descriptor **lsd,const char *base)
+{
+ alloc_lsd(lsd);
+ (*lsd)->lsd_base=xstrdup(base);
+}
+
+static void do_setscope(struct ldap_service_search_descriptor **lsd,int scope)
+{
+ alloc_lsd(lsd);
+ (*lsd)->lsd_scope=scope;
+}
+
+static void do_setfilter(struct ldap_service_search_descriptor **lsd,const char *filter)
+{
+ alloc_lsd(lsd);
+ (*lsd)->lsd_filter=xstrdup(filter);;
+}
+
+/* split a line from the configuration file
+ note that this code is not thread safe!
+ the line value will be rewritten! */
+static const char **tokenize(const char *filename,int lnr,char *line,int *nopt)
+{
+ static const char *retv[MAX_LINE_OPTIONS];
+ int opt;
+ for (opt=0;opt<MAX_LINE_OPTIONS;opt++)
+ {
+ /* skip beginning spaces */
+ while ((*line==' ')||(*line=='\t'))
+ line++;
+ /* check for end of line or comment */
+ if ((*line=='\0')||(*line=='#'))
+ break; /* we're done */
+ /* we have a new keyword */
+ retv[opt]=line;
+ if (*line=='"')
{
- *t = (struct ldap_service_search_descriptor *) * buffer;
- cur = *t;
+ line++;
+ /* find end quote */
+ while ((*line!='"')&&(*line!='\0'))
+ line++;
+ if (*line!='"')
+ {
+ log_log(LOG_ERR,"%s:%d: quoted value not terminated",filename,lnr);
+ exit(EXIT_FAILURE);
+ }
+ line++;
}
- else
+ else
{
- cur->lsd_next = (struct ldap_service_search_descriptor *) * buffer;
- cur = cur->lsd_next;
+ /* find the end of the token */
+ while ((*line!=' ')&&(*line!='\t')&&(*line!='\0'))
+ line++;
}
+ /* mark the end of the token */
+ if (*line!='\0')
+ *line++='\0';
+ }
+ *nopt=opt;
+ return retv;
+}
- 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;
+/* check that the condition is true and otherwise log an error
+ and bail out */
+static inline void check_argumentcount(const char *filename,int lnr,
+ const char *keyword,int condition)
+{
+ if (!condition)
+ {
+ log_log(LOG_ERR,"%s:%d: %s: wrong number of arguments",filename,lnr,keyword);
+ exit(EXIT_FAILURE);
+ }
}
-static enum nss_status _nss_ldap_readconfig(struct ldap_config ** presult, char **buffer, size_t *buflen)
+static void cfg_read(const char *filename,struct ldap_config *cfg)
{
FILE *fp;
- char b[NSS_LDAP_CONFIG_BUFSIZ];
- enum nss_status status = NSS_STATUS_SUCCESS;
- struct ldap_config *result;
+ int lnr=0;
+ char line[MAX_LINE_LENGTH];
+ int i;
+ const char **opts;
+ int nopts;
- if (bytesleft (*buffer, *buflen, struct ldap_config *) < sizeof (struct ldap_config))
+ /* open config file */
+ if ((fp=fopen (filename, "r"))==NULL)
{
- return NSS_STATUS_TRYAGAIN;
+ log_log(LOG_ERR,"cannot open config file (%s): %s",filename,strerror(errno));
+ exit(EXIT_FAILURE);
}
- align (*buffer, *buflen, struct ldap_config *);
- result = *presult = (struct ldap_config *) *buffer;
- *buffer += sizeof (struct ldap_config);
- *buflen -= sizeof (struct ldap_config);
-
- _nss_ldap_init_config(result);
-
- fp = fopen (NSS_LDAP_PATH_CONF, "r");
- if (fp == NULL)
- {
- return NSS_STATUS_UNAVAIL;
- }
-
- 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;
- }
-
- 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_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_DEBUG))
- {
- result->ldc_debug = atoi (v);
- }
- else if (!strcasecmp (k, NSS_LDAP_KEY_PAGESIZE))
- {
- result->ldc_pagesize = atoi (v);
- }
+
+ /* read file and parse lines */
+ while (fgets(line,MAX_LINE_LENGTH,fp)!=NULL)
+ {
+ lnr++;
+ /* strip newline */
+ i=(int)strlen(line);
+ if ((i<=0)||(line[i-1]!='\n'))
+ {
+ log_log(LOG_ERR,"%s:%d: line too long or last line missing newline",filename,lnr);
+ exit(EXIT_FAILURE);
+ }
+ line[i-1]='\0';
+ /* split the line in tokens */
+ opts=tokenize(filename,lnr,line,&nopts);
+
+ /* ignore empty lines */
+ if (nopts==0)
+ continue;
+
+ /* TODO: replace atoi() calls with proper parser routine with checks */
+
+ /* general connection options */
+ if (strcasecmp(opts[0],"uri")==0)
+ {
+ check_argumentcount(filename,lnr,opts[0],nopts>1);
+ for (i=1;i<nopts;i++)
+ add_uri(filename,lnr,cfg,opts[i]);
+ }
+ else if (strcasecmp(opts[0],"ldap_version")==0)
+ {
+ check_argumentcount(filename,lnr,opts[0],nopts==2);
+ cfg->ldc_version=atoi(opts[1]);
+ }
+ else if (strcasecmp(opts[0],"binddn")==0)
+ {
+ check_argumentcount(filename,lnr,opts[0],nopts==2);
+ cfg->ldc_binddn=xstrdup(opts[1]);
+ }
+ else if (strcasecmp(opts[0],"bindpw")==0)
+ {
+ check_argumentcount(filename,lnr,opts[0],nopts==2);
+ cfg->ldc_bindpw=xstrdup(opts[1]);
+ }
+ else if (strcasecmp(opts[0],"rootbinddn")==0)
+ {
+ check_argumentcount(filename,lnr,opts[0],nopts==2);
+ cfg->ldc_rootbinddn=xstrdup(opts[1]);
+ }
+ else if (strcasecmp(opts[0],"rootbindpw")==0)
+ {
+ check_argumentcount(filename,lnr,opts[0],nopts==2);
+ cfg->ldc_rootbindpw=xstrdup(opts[1]);
+ }
+ /* SASL authentication options */
+ else if (strcasecmp(opts[0], "sasl_authid")==0)
+ {
+ check_argumentcount(filename,lnr,opts[0],nopts==2);
+ cfg->ldc_saslid=xstrdup(opts[1]);
+ }
+ else if (strcasecmp(opts[0],"rootsasl_authid")==0)
+ {
+ check_argumentcount(filename,lnr,opts[0],nopts==2);
+ cfg->ldc_rootsaslid=xstrdup(opts[1]);
+ }
+ else if (strcasecmp(opts[0],"sasl_secprops")==0)
+ {
+ check_argumentcount(filename,lnr,opts[0],nopts==2);
+ cfg->ldc_sasl_secprops=xstrdup(opts[1]);
+ }
+ else if (strcasecmp(opts[0],"use_sasl")==0)
+ {
+ check_argumentcount(filename,lnr,opts[0],nopts==2);
+ cfg->ldc_usesasl=parse_boolean(filename,lnr,opts[1]);
+ }
+ else if (strcasecmp(opts[0],"rootuse_sasl")==0)
+ {
+ check_argumentcount(filename,lnr,opts[0],nopts==2);
+ cfg->ldc_rootusesasl=parse_boolean(filename,lnr,opts[1]);
+ }
#ifdef CONFIGURE_KRB5_CCNAME
- else if (!strcasecmp (k, NSS_LDAP_KEY_KRB5_CCNAME))
- {
- t = &result->ldc_krb5_ccname;
- }
+ /* Kerberos authentication options */
+ else if (strcasecmp(opts[0],"krb5_ccname")==0)
+ {
+ check_argumentcount(filename,lnr,opts[0],nopts==2);
+ cfg->ldc_krb5_ccname=xstrdup(opts[1]);
+ }
#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,
- strlen (NSS_LDAP_KEY_MAP)))
- {
- do_parse_map_statement (result, v);
- }
- 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_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);
- }
- }
+ /* search/mapping options */
+ else if (strcasecmp(opts[0],"base")==0)
+ {
+ if (nopts==2)
+ cfg->ldc_base=xstrdup(opts[1]);
+ else if (nopts==3)
+ do_setbase(&(cfg->ldc_sds[parse_map(filename,lnr,opts[1])]),opts[2]);
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_uris[0] == NULL)
- {
- status = NSS_STATUS_NOTFOUND;
- }
-
- return status;
+ check_argumentcount(filename,lnr,opts[0],0);
+ }
+ else if (strcasecmp(opts[0],"scope")==0)
+ {
+ if (nopts==2)
+ cfg->ldc_scope=parse_scope(filename,lnr,opts[1]);
+ else if (nopts==3)
+ do_setscope(&(cfg->ldc_sds[parse_map(filename,lnr,opts[1])]),parse_scope(filename,lnr,opts[2]));
+ else
+ check_argumentcount(filename,lnr,opts[0],0);
+ }
+ else if (strcasecmp(opts[0],"deref")==0)
+ {
+ check_argumentcount(filename,lnr,opts[0],nopts==2);
+ if (strcasecmp(opts[1],"never")==0)
+ cfg->ldc_deref=LDAP_DEREF_NEVER;
+ else if (strcasecmp(opts[1],"searching")==0)
+ cfg->ldc_deref=LDAP_DEREF_SEARCHING;
+ else if (strcasecmp(opts[1],"finding")==0)
+ cfg->ldc_deref=LDAP_DEREF_FINDING;
+ else if (strcasecmp(opts[1],"always")==0)
+ cfg->ldc_deref=LDAP_DEREF_ALWAYS;
+ else
+ {
+ log_log(LOG_ERR,"%s:%d: wrong argument: '%s'",filename,lnr,opts[1]);
+ exit(EXIT_FAILURE);
+ }
+ }
+ else if (strcasecmp(opts[0],"referrals")==0)
+ {
+ check_argumentcount(filename,lnr,opts[0],nopts==2);
+ cfg->ldc_referrals=parse_boolean(filename,lnr,opts[1]);
+ }
+ else if (strcasecmp(opts[0],"filter")==0)
+ {
+ check_argumentcount(filename,lnr,opts[0],nopts==3);
+ do_setfilter(&(cfg->ldc_sds[parse_map(filename,lnr,opts[1])]),opts[2]);
+ }
+ else if (strcasecmp(opts[0],"map")==0)
+ {
+ check_argumentcount(filename,lnr,opts[0],nopts==4);
+ parse_map_statement(filename,lnr,cfg,opts);
+ }
+ /* timing/reconnect options */
+ else if (strcasecmp(opts[0],"timelimit")==0)
+ {
+ check_argumentcount(filename,lnr,opts[0],nopts==2);
+ cfg->ldc_timelimit=atoi(opts[1]);
+ }
+ else if (strcasecmp(opts[0],"bind_timelimit")==0)
+ {
+ check_argumentcount(filename,lnr,opts[0],nopts==2);
+ cfg->ldc_bind_timelimit=atoi(opts[1]);
+ }
+ else if (strcasecmp(opts[0],"bind_policy")==0)
+ {
+ check_argumentcount(filename,lnr,opts[0],nopts==2);
+ if ( (strcasecmp(opts[1],"hard")==0) ||
+ (strcasecmp(opts[1],"hard_open")==0) )
+ cfg->ldc_reconnect_pol=LP_RECONNECT_HARD_OPEN;
+ else if (strcasecmp(opts[1],"hard_init")==0)
+ cfg->ldc_reconnect_pol=LP_RECONNECT_HARD_INIT;
+ else if (strcasecmp(opts[1],"soft")==0)
+ cfg->ldc_reconnect_pol=LP_RECONNECT_SOFT;
+ }
+ else if (strcasecmp(opts[0],"nss_connect_policy")==0)
+ {
+ check_argumentcount(filename,lnr,opts[0],nopts==2);
+ if (!strcasecmp(opts[1],"oneshot"))
+ cfg->ldc_flags|=NSS_LDAP_FLAGS_CONNECT_POLICY_ONESHOT;
+ else if (!strcasecmp(opts[1],"persist"))
+ cfg->ldc_flags&=~(NSS_LDAP_FLAGS_CONNECT_POLICY_ONESHOT);
+ }
+ else if (strcasecmp(opts[0],"idle_timelimit")==0)
+ {
+ check_argumentcount(filename,lnr,opts[0],nopts==2);
+ cfg->ldc_idle_timelimit=atoi(opts[1]);
+ }
+ /* SSL/TLS options */
+ else if (strcasecmp(opts[0],"ssl")==0)
+ {
+ check_argumentcount(filename,lnr,opts[0],nopts==2);
+ if (strcasecmp(opts[1],"start_tls")==0)
+ cfg->ldc_ssl_on=SSL_START_TLS;
+ else if (parse_boolean(filename,lnr,opts[1]))
+ cfg->ldc_ssl_on=SSL_LDAPS;
+ }
+ else if (strcasecmp(opts[0],"sslpath")==0)
+ {
+ check_argumentcount(filename,lnr,opts[0],nopts==2);
+ cfg->ldc_sslpath=xstrdup(opts[1]);
+ }
+ else if (strcasecmp(opts[0],"tls_checkpeer")==0)
+ {
+ check_argumentcount(filename,lnr,opts[0],nopts==2);
+ cfg->ldc_tls_checkpeer=parse_boolean(filename,lnr,opts[1]);
+ }
+ else if (strcasecmp(opts[0],"tls_cacertdir")==0)
+ {
+ check_argumentcount(filename,lnr,opts[0],nopts==2);
+ cfg->ldc_tls_cacertdir=xstrdup(opts[1]);
+ }
+ else if (strcasecmp(opts[0],"tls_cacertfile")==0)
+ {
+ check_argumentcount(filename,lnr,opts[0],nopts==2);
+ cfg->ldc_tls_cacertfile=xstrdup(opts[1]);
+ }
+ else if (strcasecmp(opts[0],"tls_randfile")==0)
+ {
+ check_argumentcount(filename,lnr,opts[0],nopts==2);
+ cfg->ldc_tls_randfile=xstrdup(opts[1]);
+ }
+ else if (strcasecmp(opts[0],"tls_ciphers")==0)
+ {
+ check_argumentcount(filename,lnr,opts[0],nopts==2);
+ cfg->ldc_tls_ciphers=xstrdup(opts[1]);
+ }
+ else if (strcasecmp(opts[0],"tls_cert")==0)
+ {
+ check_argumentcount(filename,lnr,opts[0],nopts==2);
+ cfg->ldc_tls_cert=xstrdup(opts[1]);
+ }
+ else if (strcasecmp(opts[0],"tls_key")==0)
+ {
+ check_argumentcount(filename,lnr,opts[0],nopts==2);
+ cfg->ldc_tls_key=xstrdup(opts[1]);
+ }
+ /* other options */
+ else if (strcasecmp(opts[0],"restart")==0)
+ {
+ check_argumentcount(filename,lnr,opts[0],nopts==2);
+ cfg->ldc_restart=parse_boolean(filename,lnr,opts[1]);
+ }
+ else if (strcasecmp(opts[0],"pagesize")==0)
+ {
+ check_argumentcount(filename,lnr,opts[0],nopts==2);
+ cfg->ldc_pagesize=atoi(opts[1]);
+ }
+ else if (strcasecmp(opts[0],"nss_schema")==0)
+ {
+ check_argumentcount(filename,lnr,opts[0],nopts==2);
+ if (strcasecmp(opts[1],"rfc2307bis")==0)
+ cfg->ldc_flags|=NSS_LDAP_FLAGS_RFC2307BIS;
+ else if (strcasecmp(opts[1],"rfc2307")==0)
+ cfg->ldc_flags&=~(NSS_LDAP_FLAGS_RFC2307BIS);
+ else
+ {
+ log_log(LOG_ERR,"%s:%d: wrong argument: '%s'",filename,lnr,opts[1]);
+ exit(EXIT_FAILURE);
+ }
+ }
+ /* undocumented options */
+ else if (strcasecmp(opts[0],"nss_reconnect_tries")==0)
+ {
+ check_argumentcount(filename,lnr,opts[0],nopts==2);
+ cfg->ldc_reconnect_tries=atoi(opts[1]);
+ }
+ else if (!strcasecmp(opts[0],"nss_reconnect_sleeptime"))
+ {
+ check_argumentcount(filename,lnr,opts[0],nopts==2);
+ cfg->ldc_reconnect_sleeptime=atoi(opts[1]);
+ }
+ else if (strcasecmp(opts[0],"nss_reconnect_maxsleeptime")==0)
+ {
+ check_argumentcount(filename,lnr,opts[0],nopts==2);
+ cfg->ldc_reconnect_maxsleeptime=atoi(opts[1]);
+ }
+ else if (strcasecmp(opts[0],"nss_reconnect_maxconntries")==0)
+ {
+ check_argumentcount(filename,lnr,opts[0],nopts==2);
+ cfg->ldc_reconnect_maxconntries=atoi(opts[1]);
+ }
+ else
+ {
+ log_log(LOG_ERR,"%s:%d: unknown keyword: '%s'",filename,lnr,opts[0]);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ /* we're done reading file, close */
+ fclose(fp);
}
-int cfg_init(void)
+void cfg_init(void)
{
- static char configbuf[NSS_LDAP_CONFIG_BUFSIZ];
- char *configbufp;
- size_t configbuflen;
- enum nss_status retv;
if (nslcd_cfg==NULL)
{
- configbufp=configbuf;
- configbuflen=sizeof(configbuf);
- retv=_nss_ldap_readconfig(&nslcd_cfg,&configbufp,&configbuflen);
- if (retv!=NSS_STATUS_SUCCESS)
+ /* allocate the memory */
+ nslcd_cfg=(struct ldap_config *)malloc(sizeof(struct ldap_config));
+ if (nslcd_cfg==NULL)
+ {
+ log_log(LOG_CRIT,"malloc() failed to allocate memory");
+ exit(EXIT_FAILURE);
+ }
+ /* clear configuration */
+ cfg_defaults(nslcd_cfg);
+ /* read configfile */
+ cfg_read(NSS_LDAP_PATH_CONF,nslcd_cfg);
+ /* do some sanity checks */
+ if (nslcd_cfg->ldc_uris[0] == NULL)
{
- log_log(LOG_DEBUG,"cfg_init() failed to read config");
- return -1;
+ log_log(LOG_ERR,"no URIs defined in config");
+ exit(EXIT_FAILURE);
}
}
- return 0;
}
diff --git a/nslcd/cfg.h b/nslcd/cfg.h
index c790c57..0709ebf 100644
--- a/nslcd/cfg.h
+++ b/nslcd/cfg.h
@@ -63,82 +63,90 @@ enum ldap_shadow_selector
struct ldap_config
{
/* NULL terminated list of URIs */
- char *ldc_uris[NSS_LDAP_CONFIG_URI_MAX + 1];
- /* base DN, eg. dc=gnu,dc=org */
- char *ldc_base;
- /* scope for searches */
- int ldc_scope;
- /* dereference aliases/links */
- int ldc_deref;
+ char *ldc_uris[NSS_LDAP_CONFIG_URI_MAX+1];
+ /* protocol version */
+ int ldc_version;
/* bind DN */
char *ldc_binddn;
/* bind cred */
char *ldc_bindpw;
- /* do we use sasl when binding? */
- int ldc_usesasl;
- /* sasl auth id */
- char *ldc_saslid;
- /* shadow bind DN */
+ /* bind DN for root processes */
char *ldc_rootbinddn;
- /* shadow bind cred */
+ /* bind cred for root processes */
char *ldc_rootbindpw;
- /* do we use sasl for root? */
- int ldc_rootusesasl;
+ /* sasl auth id */
+ char *ldc_saslid;
/* shadow sasl auth id */
char *ldc_rootsaslid;
- /* protocol version */
- int ldc_version;
+ /* sasl security */
+ char *ldc_sasl_secprops;
+ /* do we use sasl when binding? */
+ int ldc_usesasl;
+ /* do we use sasl for root? */
+ int ldc_rootusesasl;
+#ifdef CONFIGURE_KRB5_CCNAME
+ /* krb5 ccache name */
+ char *ldc_krb5_ccname;
+#endif /* CONFIGURE_KRB5_CCNAME */
+ /* base DN, eg. dc=gnu,dc=org */
+ char *ldc_base;
+ /* scope for searches */
+ int ldc_scope;
+ /* dereference aliases/links */
+ int ldc_deref;
+ /* Chase referrals */
+ int ldc_referrals;
+ /* naming contexts */
+ struct ldap_service_search_descriptor *ldc_sds[LM_NONE];
/* search timelimit */
int ldc_timelimit;
/* bind timelimit */
int ldc_bind_timelimit;
+ /* reconnect policy */
+ enum ldap_reconnect_policy ldc_reconnect_pol;
+ /* for nss_connect_policy and nss_schema */
+ unsigned int ldc_flags;
+ /* idle timeout */
+ time_t ldc_idle_timelimit;
/* SSL enabled */
enum ldap_ssl_options ldc_ssl_on;
/* SSL certificate path */
char *ldc_sslpath;
- /* Chase referrals */
- int ldc_referrals;
- int ldc_restart;
- /* naming contexts */
- struct ldap_service_search_descriptor *ldc_sds[LM_NONE];
/* tls check peer */
int ldc_tls_checkpeer;
- /* tls ca certificate file */
- char *ldc_tls_cacertfile;
/* tls ca certificate dir */
char *ldc_tls_cacertdir;
+ /* tls ca certificate file */
+ char *ldc_tls_cacertfile;
+ /* tls randfile */
+ char *ldc_tls_randfile;
/* tls ciphersuite */
char *ldc_tls_ciphers;
/* tls certificate */
char *ldc_tls_cert;
/* tls key */
char *ldc_tls_key;
- /* tls randfile */
- char *ldc_tls_randfile;
- /* idle timeout */
- time_t ldc_idle_timelimit;
- /* reconnect policy */
- enum ldap_reconnect_policy ldc_reconnect_pol;
+ /* whether the LDAP library should restart the select(2) system call when interrupted */
+ int ldc_restart;
+ /* set to a greater than 0 to enable handling of paged results with the specified size */
+ int ldc_pagesize;
+ /* undocumented settings */
int ldc_reconnect_tries;
int ldc_reconnect_sleeptime;
int ldc_reconnect_maxsleeptime;
int ldc_reconnect_maxconntries;
- /* sasl security */
- char *ldc_sasl_secprops;
/* LDAP debug level */
int ldc_debug;
- int ldc_pagesize;
-#ifdef CONFIGURE_KRB5_CCNAME
- /* krb5 ccache name */
- char *ldc_krb5_ccname;
-#endif /* CONFIGURE_KRB5_CCNAME */
- /* is userPassword "userPassword" or not? ie. do we need {crypt} to be stripped */
+ /* is userPassword "userPassword" or not? ie. do we need {crypt} to be stripped
+ (silently set when mapping is done) TODO: replace this with some runtime detection */
enum ldap_userpassword_selector ldc_password_type;
- /* Use active directory time offsets? */
+ /* Use active directory time offsets?
+ (silently set when mapping is done) TODO: replace this with some runtime detection */
enum ldap_shadow_selector ldc_shadow_type;
- unsigned int ldc_flags;
};
+/* this is a pointer to the global configuration, it should be available
+ once cfg_init() was called */
extern struct ldap_config *nslcd_cfg;
/*
@@ -150,7 +158,9 @@ extern struct ldap_config *nslcd_cfg;
int _nss_ldap_test_config_flag(unsigned int flag)
MUST_USE;
-int cfg_init(void)
- MUST_USE;
+/* Initialize the configuration in nslcd_cfg. This method
+ will read the default configuration file and call exit()
+ if an error occurs. */
+void cfg_init(void);
#endif /* _CFG_H */
diff --git a/nslcd/ldap-nss.c b/nslcd/ldap-nss.c
index a9530a8..ed68dc5 100644
--- a/nslcd/ldap-nss.c
+++ b/nslcd/ldap-nss.c
@@ -798,10 +798,6 @@ do_init (void)
log_log(LOG_DEBUG,"==> do_init");
- /* Initialize schema and LDAP handle (but do not connect) */
- cfg_init();
- /* FIXME: if config was reloaded, do_close() and set __session.ls_current_uri=0 */
-
if (__session.ls_state == LS_CONNECTED_TO_DSA)
{
time_t current_time;
diff --git a/nslcd/ldap-schema.h b/nslcd/ldap-schema.h
index aeb6c34..391c883 100644
--- a/nslcd/ldap-schema.h
+++ b/nslcd/ldap-schema.h
@@ -92,20 +92,4 @@ extern char _nss_ldap_filt_getspent[];
/* netgroups */
extern char _nss_ldap_filt_getnetgrent[];
-/*
- * Map names
- */
-#define MP_passwd "passwd"
-#define MP_shadow "shadow"
-#define MP_group "group"
-#define MP_hosts "hosts"
-#define MP_services "services"
-#define MP_networks "networks"
-#define MP_protocols "protocols"
-#define MP_rpc "rpc"
-#define MP_ethers "ethers"
-#define MP_netmasks "netmasks"
-#define MP_aliases "aliases"
-#define MP_netgroup "netgroup"
-
#endif /* _LDAP_NSS_LDAP_LDAP_SCHEMA_H */
diff --git a/nslcd/nslcd.c b/nslcd/nslcd.c
index 35fe3ed..a4c5dca 100644
--- a/nslcd/nslcd.c
+++ b/nslcd/nslcd.c
@@ -48,6 +48,7 @@
#include "nslcd.h"
#include "log.h"
+#include "cfg.h"
#include "common.h"
#include "compat/attrs.h"
@@ -540,6 +541,10 @@ int main(int argc,char *argv[])
if (__nss_configure_lookup("hosts","files dns"))
log_log(LOG_ERR,"unable to override hosts lookup method: %s",strerror(errno));
+ /* read configuration file */
+ cfg_init();
+ nslcd_cfg->ldc_debug=nslcd_debugging;
+
/* daemonize */
if ((!nslcd_debugging)&&(daemon(0,0)<0))
{
@@ -551,7 +556,7 @@ int main(int argc,char *argv[])
(void)umask((mode_t)0022);
/* intilialize logging */
- if (!nslcd_debugging)
+ if (!nslcd_cfg->ldc_debug)
log_startlogging();
log_log(LOG_INFO,"version %s starting",VERSION);