summaryrefslogtreecommitdiff
path: root/nslcd
diff options
context:
space:
mode:
authorArthur de Jong <arthur@arthurdejong.org>2007-08-18 19:35:56 +0000
committerArthur de Jong <arthur@arthurdejong.org>2007-08-18 19:35:56 +0000
commit3d531f6a73d6af0ad5444f9ddeb7cd6ac8fec64e (patch)
tree2825de651d7c8cdd76dc821b640aaa3795cc0772 /nslcd
parent1a79a08b416d2c611afd51d143c4d74efecd7b9e (diff)
rewrite configuration file handling to be simpler and more consistent, this does mean that the syntax of the configfile has changed from the PADL one and that some options were removed (also update manual page and sample config file to reflect changes)
git-svn-id: http://arthurdejong.org/svn/nss-pam-ldapd/nss-ldapd@343 ef36b2f9-881f-0410-afb5-c4e39611909c
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);