From 3d531f6a73d6af0ad5444f9ddeb7cd6ac8fec64e Mon Sep 17 00:00:00 2001 From: Arthur de Jong Date: Sat, 18 Aug 2007 19:35:56 +0000 Subject: 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 --- configure.ac | 8 - man/nss-ldapd.conf.5.xml | 482 +++++++++---------- nslcd/attmap.c | 128 ++--- nslcd/attmap.h | 3 +- nslcd/cfg.c | 1205 +++++++++++++++++++++------------------------- nslcd/cfg.h | 94 ++-- nslcd/ldap-nss.c | 4 - nslcd/ldap-schema.h | 16 - nslcd/nslcd.c | 7 +- nss-ldapd.conf | 183 +++---- 10 files changed, 976 insertions(+), 1154 deletions(-) diff --git a/configure.ac b/configure.ac index e69a79f..3dba332 100644 --- a/configure.ac +++ b/configure.ac @@ -107,14 +107,6 @@ AC_ARG_WITH(ldap-conf-file, AC_DEFINE_UNQUOTED(NSS_LDAP_PATH_CONF,"$NSS_LDAP_PATH_CONF",[Path to LDAP configuration file.]) AC_SUBST(NSS_LDAP_PATH_CONF) -AC_ARG_WITH(ldap-secret-file, - AS_HELP_STRING([--with-ldap-secret-file=PATH], - [path to LDAP root secret file @<:@/etc/nss-ldapd.secret@:>@]), - [ NSS_LDAP_PATH_ROOTPASSWD="$with_ldap_secret_file" ], - [ NSS_LDAP_PATH_ROOTPASSWD="/etc/nss-ldapd.secret" ]) -AC_DEFINE_UNQUOTED(NSS_LDAP_PATH_ROOTPASSWD,"$NSS_LDAP_PATH_ROOTPASSWD",[Path to LDAP root secret file.]) -AC_SUBST(NSS_LDAP_PATH_ROOTPASSWD) - AC_ARG_WITH(nslcd-pidfile, AS_HELP_STRING([--with-nslcd-pidfile=PATH], [path to pidfile @<:@/var/run/nslcd/nslcd.pid@:>@]), diff --git a/man/nss-ldapd.conf.5.xml b/man/nss-ldapd.conf.5.xml index 404e27e..d88f441 100644 --- a/man/nss-ldapd.conf.5.xml +++ b/man/nss-ldapd.conf.5.xml @@ -21,7 +21,7 @@ You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110\-1301 USA + 02110-1301 USA --> @@ -201,6 +201,7 @@ + + Search/mapping options - - base <base> - - Specifies the default base distinguished name (DN) to use for searches. - - - - - scope <sub|one|base> + + + MAP + DN - Specifies the search scope (subtree, one level or base object). The - default scope is subtree; base scope is almost never useful for - nameservice lookups. + + Specifies the base distinguished name (DN) + to use as search base. + A global search base may be specified or a MAP-specific one. + If no MAP-specific search base is defined the global one is used. + - + - - deref <never|searching|finding|always> + + + MAP + subtree|onelevel|base - Specifies the policy for dereferencing aliases. The default policy is - to never dereference aliases. + + Specifies the search scope (subtree, one level or base object). + The default scope is subtree; base scope is almost never useful for + nameservice lookups. + - + - - referrals <yes|no> + + never|searching|finding|always - Specifies whether automatic referral chasing should be enabled. The - default behaviour is specifed by the - LDAP - client library. - - - - - nss_base_<map> <basedn?scope?filter> - - Specify the search base, scope and filter to be used for specific - maps. (Note that - map - forms part of the configuration file keyword and is one of - passwd, shadow, group, hosts, services, networks, protocols, - rpc, ethers, netmasks, bootparams, aliases and netgroup.) - The syntax of - basedn - and - scope - are the same as for the configuration file options of the same - name, with the addition of being able to omit the trailing suffix - of the base DN (in which case the global base DN will be appended - instead). The - filter - is a search filter to be added to the default search filter for a - specific map, such that the effective filter is the logical - intersection of the two. The base DN, scope and filter are separated - with literal question marks (?) as given above; this is for - compatibility with the DUA configuration profile schema and the - ldapprofile - tool. This option may be specified multiple times. + + Specifies the policy for dereferencing aliases. + The default policy is to never dereference aliases. + - + - - nss_map_attribute <from_attribute> <to_attribute> + + yes|no - This option may be specified multiple times, and directs - nss_ldap - to use the attribute - to_attribute - instead of the RFC 2307 attribute - from_attribute - in all lookups. - If - nss_ldap - was built without schema mapping support, then this option - is ignored. + + Specifies whether automatic referral chasing should be enabled. + The default behaviour is to chase referrals. + - + - - nss_map_objectclass <from_objectclass> <to_objectclass> + + + MAP + FILTER - This option may be specified multiple times, and directs - nss_ldap - to use the object class - to_objectclass - instead of the RFC 2307 object class - from_objectclass - in all lookups. - If - nss_ldap - was built without schema mapping support, then this option - is ignored. + + The FILTER + is an LDAP search filter to use for a + specific map. + The default filter is a basic search on the + objectClass for the map (e.g. (objectClass=posixAccount)). + - + - - nss_default_attribute_value <attribute> <value> + + + MAP + ATTRIBUTE + NEWATTRIBUTE - Specifies the default value to use for entries that lack the - specified attribute. This option may be specified multiple times, - for different attributes. - If - nss_ldap - was built without schema mapping support, then this option - is ignored. + + This option allows for custom attributes to be looked up instead of + the default RFC 2307 attributes that are used. + The MAP may be one of + the supported maps below. + The ATTRIBUTE is the one as + used in RFC 2307 (e.g. userPassword, + ipProtocolNumber or macAddress). + The NEWATTRIBUTE may be any attribute + as it is available in the directory. + + - + - - nss_override_attribute_value <attribute> <value> + @@ -392,68 +380,68 @@ Timing/reconnect options - + timelimit <timelimit> - Specifies the time limit (in seconds) to use when performing searches. A value - of zero (0), which is the default, is to wait indefinitely for - searches to be completed. + Specifies the time limit (in seconds) to use when performing searches. A value + of zero (0), which is the default, is to wait indefinitely for + searches to be completed. - + - + bind_timelimit <timelimit> - Specifies the time limit (in seconds) to use when connecting to the directory - server. This is distinct from the time limit specified in - timelimit - and affects the initial server connection only. (Server connections - are otherwise cached.) Only some - LDAP - client libraries have the underlying functionality necessary to - support this option. The default bind timelimit is 30 seconds. + Specifies the time limit (in seconds) to use when connecting to the directory + server. This is distinct from the time limit specified in + timelimit + and affects the initial server connection only. (Server connections + are otherwise cached.) Only some + LDAP + client libraries have the underlying functionality necessary to + support this option. The default bind timelimit is 30 seconds. - + - + bind_policy <hard_open|hard_init|soft> - Specifies the policy to use for reconnecting to an unavailable - LDAP - server. The default is - hard_open, - which reconnects if opening the connection to the directory server - failed. By contrast, - hard_init - reconnects if initializing the connection failed. Initializing may not - actually contact the directory server, and it is possible that a - malformed configuration file will trigger reconnection. If - soft - is specified, then - nss_ldap - will return immediately on server failure. All "hard" reconnect - policies block with exponential backoff before retrying. + Specifies the policy to use for reconnecting to an unavailable + LDAP + server. The default is + hard_open, + which reconnects if opening the connection to the directory server + failed. By contrast, + hard_init + reconnects if initializing the connection failed. Initializing may not + actually contact the directory server, and it is possible that a + malformed configuration file will trigger reconnection. If + soft + is specified, then + nss_ldap + will return immediately on server failure. All "hard" reconnect + policies block with exponential backoff before retrying. - + - + nss_connect_policy <persist|oneshot> - Determines whether nss_ldap persists connections. The default - is for the connection to the LDAP server to remain open after - the first request. + Determines whether nss_ldap persists connections. The default + is for the connection to the LDAP server to remain open after + the first request. - + - + idle_timelimit <timelimit> - Specifies the time (in seconds) after which - nss_ldap - will close connections to the directory server. The default is not to - time out connections. + Specifies the time (in seconds) after which + nss_ldap + will close connections to the directory server. The default is not to + time out connections. - + @@ -462,89 +450,87 @@ SSL/TLS options - + ssl <on|off|start_tls> - Specifies whether to use SSL/TLS or not (the default is not to). If - start_tls - is specified then StartTLS is used rather than raw LDAP over SSL. - Not all - LDAP - client libraries support both SSL and StartTLS, and all related - configuration options. + Specifies whether to use SSL/TLS or not (the default is not to). If + start_tls + is specified then StartTLS is used rather than raw LDAP over SSL. + Not all LDAP client libraries support both SSL + and StartTLS, and all related configuration options. - + - + sslpath <cert7_path> - For the Netscape and Mozilla - LDAP - client libraries only, this specifies the path to the X.509 - certificate database. + For the Netscape and Mozilla + LDAP + client libraries only, this specifies the path to the X.509 + certificate database. - + - + tls_checkpeer <yes|no> - Specifies whether to require and verify the server certificate - or not, when using SSL/TLS with the OpenLDAP client library. - The default is to use the default behaviour of the client - library; for OpenLDAP 2.0 and earlier it is "no", for OpenLDAP - 2.1 and later it is "yes". At least one of - tls_cacertdir - and - tls_cacertfile - is required if peer verification is enabled. + Specifies whether to require and verify the server certificate + or not, when using SSL/TLS with the OpenLDAP client library. + The default is to use the default behaviour of the client + library; for OpenLDAP 2.0 and earlier it is "no", for OpenLDAP + 2.1 and later it is "yes". At least one of + tls_cacertdir + and + tls_cacertfile + is required if peer verification is enabled. - + - + tls_cacertdir <certificate_dir> - Specifies the directory containing X.509 certificates for peer - authentication. + Specifies the directory containing X.509 certificates for peer + authentication. - + - + tls_cacertfile <certificate_file> - Specifies the path to the X.509 certificate for peer authentication. + Specifies the path to the X.509 certificate for peer authentication. - + - + tls_randfile <entropy_file> - Specifies the path to an entropy source. + Specifies the path to an entropy source. - + - + tls_ciphers <ciphers> - Specifies the ciphers to use for TLS. See your TLS implementation's - documentation for further information. + Specifies the ciphers to use for TLS. See your TLS implementation's + documentation for further information. - + - + tls_cert <certificate_file> - Specifies the path to the file containing the local certificate for - client TLS authentication. + Specifies the path to the file containing the local certificate for + client TLS authentication. - + - + tls_key <key_file> - Specifies the path to the file containing the private key for client - TLS authentication. + Specifies the path to the file containing the private key for client + TLS authentication. - + @@ -566,31 +552,6 @@ - - logdir <directory> - - Specifies the directory used for logging by the - LDAP - client library. This feature is not supported by all client - libraries. - - - - - debug <level> - - Specifies the debug level used for logging by the - LDAP - client library. This feature is not supported by all client - libraries, and does not apply to the - nss_ldap - and - pam_ldap - modules themselves (debugging, if any, is configured separately - and usually at compile time). - - - NUMBER @@ -614,33 +575,6 @@ TODO: remove the above option and always support mulitple schema checking based on the contenst of the directory - - nss_initgroups <backlink> - - This option directs the - nss_ldap - implementation of - initgroups(3) - to determine a user's group membership by reading the memberOf - attribute of their directory entry (and of any nested groups), - rather than querying on uniqueMember. This may provide increased - performance with certain directory servers that have peculiar - indexing configurations. - If RFC2307bis support is disabled, then this option is ignored. - - - - - nss_initgroups_ignoreusers <user1,user2,...,userN> - - This option directs the - nss_ldap - implementation of - initgroups(3) - to return NSS_STATUS_NOTFOUND if called with a listed users as - its argument. - - @@ -648,6 +582,60 @@ TODO: remove the above option and always support mulitple schema checking based + + Supported maps + + The following maps are supported. They are referenced as + MAP withthe options. + + + + alias(es) + Mail aliases (ignored by most mail servers). + + + ether(s) + Ethernet numbers (mac addresses). + + + group + Posix groups. + + + host(s) + Host names. + + + netgroup + Host and user groups used for access control. + + + network(s) + Network numbers. + + + passwd + Posix users. + + + protocol(s) + Protocol definitions (like in /etc/protocols). + + + rpc + Remote procedure call names and numbers. + + + service(s) + Network service names and numbers. + + + shadow + Shadow user password information. + + + + Files 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 #include #include +#include #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;ildc_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;optlsd_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 , 05.10.2000 */ - while (*v == ' ' || *v == '\t') - v++; - - /* kick off all whitespaces and newline at the end of value */ - /* Bob Guo , 08.10.2001 */ - - /* Also remove \r (CR) to be able to handle files in DOS format (lines - * terminated in CR LF). Alejandro Forero Cuervo - * , 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;ildc_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); diff --git a/nss-ldapd.conf b/nss-ldapd.conf index cadcb11..0fcb3c3 100644 --- a/nss-ldapd.conf +++ b/nss-ldapd.conf @@ -1,27 +1,27 @@ # This is the configuration file for the LDAP nameservice -# switch library. +# switch library's nslcd daemon. It configures the mapping +# between NSS names (see /etc/nsswitch.conf) and LDAP +# information in the directory. +# See the manual page nss-ldapd.conf(5) for more information. # The uri pointing to the LDAP server to use for name lookups. -# Mulitple entries may be specified, each separated by a -# space. The address that is used here should be resolvable -# without using LDAP (obviously). +# Mulitple entries may be specified. The address that is used +# here should be resolvable without using LDAP (obviously). #uri ldap://127.0.0.1/ #uri ldaps://127.0.0.1/ #uri ldapi://%2fvar%2frun%2fldapi_sock/ # Note: %2f encodes the '/' used as directory separator uri ldap://127.0.0.1/ -# The distinguished name of the search base. -base dc=example,dc=net - # The LDAP version to use (defaults to 3 # if supported by client library) #ldap_version 3 +# The distinguished name of the search base. +base dc=example,dc=net + # The distinguished name to bind to the server with. # Optional: default is to bind anonymously. -# Please do not put double quotes around it as they -# would be included literally. #binddn cn=proxyuser,dc=padl,dc=com # The credentials to bind with. @@ -29,17 +29,24 @@ base dc=example,dc=net #bindpw secret # The distinguished name to bind to the server with -# if the effective user ID is root. Password is -# stored in /etc/ldap.secret (mode 600) -# Use 'echo -n "mypassword" > /etc/ldap.secret' instead -# of an editor to create the file. +# if the effective user ID is root. #rootbinddn cn=manager,dc=padl,dc=com -# The search scope. +# The root credentials to bind with. +#rootbindpw secret + +# The default search scope. #scope sub #scope one #scope base +# Customize ceirtain database lookups. +#base group ou=Groups,dc=example,dc=net +#base passwd ou=People,dc=example,dc=net +#base shadow ou=People,dc=example,dc=net +#scope group onelevel +#scope hosts sub + # Search timelimit #timelimit 30 @@ -65,98 +72,56 @@ base dc=example,dc=net # for the number of seconds specified below. #idle_timelimit 3600 -# Use paged rseults -#nss_paged_results yes - -# Pagesize: when paged results enable, used to set the -# pagesize to a custom value -#pagesize 1000 - -# Use backlinks for answering initgroups() -#nss_initgroups backlink - -# Enable support for RFC2307bis (distinguished names in group -# members) -#nss_schema rfc2307bis - -# RFC2307bis naming contexts -# Syntax: -# nss_base_XXX base?scope?filter -# where scope is {base,one,sub} -# and filter is a filter to be &'d with the -# default filter. -# You can omit the suffix eg: -# nss_base_passwd ou=People, -# to append the default base DN but this -# may incur a small performance impact. -#nss_base_passwd ou=People,dc=padl,dc=com?one -#nss_base_shadow ou=People,dc=padl,dc=com?one -#nss_base_group ou=Group,dc=padl,dc=com?one -#nss_base_hosts ou=Hosts,dc=padl,dc=com?one -#nss_base_services ou=Services,dc=padl,dc=com?one -#nss_base_networks ou=Networks,dc=padl,dc=com?one -#nss_base_protocols ou=Protocols,dc=padl,dc=com?one -#nss_base_rpc ou=Rpc,dc=padl,dc=com?one -#nss_base_ethers ou=Ethers,dc=padl,dc=com?one -#nss_base_netmasks ou=Networks,dc=padl,dc=com?ne -#nss_base_bootparams ou=Ethers,dc=padl,dc=com?one -#nss_base_aliases ou=Aliases,dc=padl,dc=com?one -#nss_base_netgroup ou=Netgroup,dc=padl,dc=com?one - -# attribute/objectclass mapping -# Syntax: -#nss_map_attribute rfc2307attribute mapped_attribute -#nss_map_objectclass rfc2307objectclass mapped_objectclass - -# configure --enable-nds is no longer supported. # NDS mappings -#nss_map_attribute uniqueMember member - -# Services for UNIX 3.5 mappings -#nss_map_objectclass posixAccount User -#nss_map_objectclass shadowAccount User -#nss_map_attribute uid msSFU30Name -#nss_map_attribute uniqueMember msSFU30PosixMember -#nss_map_attribute userPassword msSFU30Password -#nss_map_attribute homeDirectory msSFU30HomeDirectory -#nss_map_attribute homeDirectory msSFUHomeDirectory -#nss_map_objectclass posixGroup Group - -# Services for UNIX 2.0 mappings -#nss_map_objectclass posixAccount User -#nss_map_objectclass shadowAccount user -#nss_map_attribute uid msSFUName -#nss_map_attribute uniqueMember posixMember -#nss_map_attribute userPassword msSFUPassword -#nss_map_attribute homeDirectory msSFUHomeDirectory -#nss_map_attribute shadowLastChange pwdLastSet -#nss_map_objectclass posixGroup Group -#nss_map_attribute cn msSFUName - -# RFC 2307 (AD) mappings -#nss_map_objectclass posixAccount user -#nss_map_objectclass shadowAccount user -#nss_map_attribute uid sAMAccountName -#nss_map_attribute gecos name -#nss_map_attribute homeDirectory unixHomeDirectory -#nss_map_attribute shadowLastChange pwdLastSet -#nss_map_objectclass posixGroup group -#nss_map_attribute uniqueMember member - -# AuthPassword mappings -#nss_map_attribute userPassword authPassword - -# AIX SecureWay mappings -#nss_map_objectclass posixAccount aixAccount -#nss_base_passwd ou=aixaccount,?one -#nss_map_attribute uid userName -#nss_map_attribute gidNumber gid -#nss_map_attribute uidNumber uid -#nss_map_attribute userPassword passwordChar -#nss_map_objectclass posixGroup aixAccessGroup -#nss_base_group ou=aixgroup,?one -#nss_map_attribute cn groupName -#nss_map_attribute uniqueMember member +#map group uniqueMember member + +# Mappings for Services for UNIX 3.5 +#filter passwd (objectClass=User) +#map passwd uid msSFU30Name +#map passwd userPassword msSFU30Password +#map passwd homeDirectory msSFU30HomeDirectory +#map passwd homeDirectory msSFUHomeDirectory +#filter shadow (objectClass=User) +#map shadow uid msSFU30Name +#map shadow userPassword msSFU30Password +#filter group (objectClass=Group) +#map group uniqueMember msSFU30PosixMember + +# Mappings for Services for UNIX 2.0 +#filter passwd (objectClass=User) +#map passwd uid msSFUName +#map passwd userPassword msSFUPassword +#map passwd homeDirectory msSFUHomeDirectory +#map passwd cn msSFUName +#filter shadow (objectClass=User) +#map shadow uid msSFUName +#map shadow userPassword msSFUPassword +#map shadow shadowLastChange pwdLastSet +#filter group (objectClass=Group) +#map group uniqueMember posixMember + +# Mappings for RFC 2307 (AD) +#filter passwd (objectClass=user) +#map passwd uid sAMAccountName +#map passwd homeDirectory unixHomeDirectory +#map passwd gecos name +#filter shadow (objectClass=user) +#map passwd uid sAMAccountName +#map shadow shadowLastChange pwdLastSet +#filter group (objectClass=group) +#map group uniqueMember member + +# Mappings for AIX SecureWay + +#filter passwd (objectClass=aixAccount) +#map passwd uid userName +#map passwd userPassword passwordChar +#map passwd uidNumber uid +#map passwd gidNumber gid +#filter group (objectClass=aixAccessGroup) +#map group cn groupName +#map group uniqueMember member +#map group gidNumber gid # Netscape SDK LDAPS #ssl on @@ -178,8 +143,8 @@ base dc=example,dc=net # CA certificates for server certificate verification # At least one of these are required if tls_checkpeer is "yes" -#tls_cacertfile /etc/ssl/ca.cert #tls_cacertdir /etc/ssl/certs +#tls_cacertfile /etc/ssl/ca.cert # Seed the PRNG if /dev/urandom is not provided #tls_randfile /var/run/egd-pool @@ -192,9 +157,3 @@ base dc=example,dc=net # Use these, if your server requires client authentication. #tls_cert #tls_key - -# Disable SASL security layers. This is needed for AD. -#sasl_secprops maxssf=0 - -# Override the default Kerberos ticket cache location. -#krb5_ccname FILE:/etc/.ldapcache -- cgit v1.2.3