diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2014-08-26 08:15:00 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2014-08-26 08:15:00 +0300 |
commit | c816d00f963cb8249a205e6fc484fc35428bb22b (patch) | |
tree | 3a5f275c8141da283321c12b906240e59711ed30 | |
parent | 124b8aa2497703558fcebe5b10b675e1d426759d (diff) | |
download | smap-c816d00f963cb8249a205e6fc484fc35428bb22b.tar.gz smap-c816d00f963cb8249a205e6fc484fc35428bb22b.tar.bz2 |
ldap: use /etc/ldap.conf by default
* NEWS: Update.
* doc/smap.texi: Document the LDAP module.
* modules/ldap/ldap.c (dfl_config_file): New static.
(make_options): New function.
(mod_ldap_init_db): Read settings from /etc/ldap.conf
(or a file specified with config-file option) first.
Then override them with the settings from the command
line.
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | doc/smap.texi | 103 | ||||
-rw-r--r-- | modules/ldap/ldap.c | 136 |
3 files changed, 188 insertions, 55 deletions
@@ -1,2 +1,2 @@ -Smap NEWS -- history of user-visible changes. 2011-03-09 +Smap NEWS -- history of user-visible changes. 2014-08-24 Copyright (C) 2006-2010, 2014 Sergey Poznyakoff @@ -9,2 +9,4 @@ Version 1.1.90, Git +* new module: ldap + diff --git a/doc/smap.texi b/doc/smap.texi index 08af20b..4bc5325 100644 --- a/doc/smap.texi +++ b/doc/smap.texi @@ -115,2 +115,3 @@ Modules Shipped with Smap * postgres:: +* ldap:: * sed:: @@ -1663,2 +1664,3 @@ in detail in the following sections. * postgres:: +* ldap:: * sed:: @@ -2382,3 +2384,3 @@ sockmap query, the database expands the SQL query template using the actual values of @samp{$@{map@}} (the map name) and -@samp{$@{key@}} (the key value) and sends the expanded query to the | +@samp{$@{key@}} (the key value) and sends the expanded query to the MySQL server. If the server responds with a non-empty set of tuples, @@ -2711,2 +2713,101 @@ Default value is @samp{NOTFOUND}. +@node ldap +@section ldap +@cindex ldap module +@cindex @acronym{LDAP} + The @command{ldap} module provides interface to the Lightweight +Directory Access Protocol. The configuration is similar to that +of SQL modules: + + The @acronym{LDAP} parameters may be configured either globally, when +loading the module, or locally, when defining a smap database. If a +database definition lacks some configuration statements, it looks them +up in a global definition. + + Each database has a @dfn{filter template} and up to three @dfn{smap +reply templates}. When dispatched a sockmap query, the database +expands the filter template using the actual values of @samp{$@{map@}} +(the map name) and @samp{$@{key@}} (the key value) and uses the +obtained filter to query the @acronym{LDAP} server. If the server +responds with a non-empty set of tuples, the @dfn{positive reply +template} is expanded and the result is used as a response. +Otherwise, if the query produced an empty set, the smap database uses +the @dfn{negative reply template} to create the response. + +@menu +* LDAP Configuration:: +* LDAP Filter and SMAP Replies:: +@end menu + +@node LDAP Configuration +@subsection LDAP Configuration + +@flindex /etc/ldap.conf +The @acronym{LDAP} configuration is read from the file +@file{/etc/ldap.conf} and from module and database command line. The +settings from the command line override those from +@file{/etc/ldap.conf}. Alternative configuration file can be +specified using the @option{config-file} option. + +@table @option +@kwindex config-file +@item config-file=@var{file} + Read configuration from file @var{file} instead of @file{/etc/ldap.conf}. + +@kwindex tls-cacert +@kwindex tls_cacert +@item tls-cacert=@var{file} +@itemx tls_cacert=@var{file} + Read TLS Certificate Authority from @var{file}. + +@kwindex uri +@item uri=@var{string} + Specifies the URI of LDAP server to connect to. Multiple URIs are +allowed. Each URI is @samp{@var{scheme}://[@var{name}[:@var{port}]]}. +The @var{scheme} part is one of: @samp{ldap}, meaning LDAP over TCP +(default port 389), @samp{ldaps}, meaning LDAP over SSL (TLS) (default +port 636), or @samp{ldapi}, meaning LDAP over UNIX socket. For +@samp{ldap} and @samp{ldaps}, @var{name} is the host name or IP +address of the remote server. Optional @var{port} specifies the TCP +port to use instead of the default one. For @samp{ldapi}, @var{name} +is the pathname of the UNIX socket and @var{port} is not used. Note, +that directory separators must be URL-encoded (using @samp{%2F} +instead of @samp{/}). + +@kwindex base +@item base=@var{string} + Sets the default base DN for ldap operations. The base must be +specified as a Distinguished Name in LDAP format. + +@kwindex binddn +@item binddn=@var{dn} + The DN to bind as. + +@kwindex bindpw +@item bindpw=@var{password} + Password for @code{binddn}. + +@kwindex bindpwfile +@item bindpwfile=@var{file} + Read password from @var{file}. This is a safer alternative to +@option{bindpw}. +@end table + +@node LDAP Filter and SMAP Replies +@subsection LDAP Filter and SMAP Replies + +@table @option +@kwindex filter +@item filter=@var{pattern} + +@kwindex positive-reply +@item positive-reply=@var{reply} + +@kwindex negative-reply +@item negative-reply=@var{reply} + +@kwindex onerror-reply +@item onerror-reply=@var{reply} +@end table + @node sed diff --git a/modules/ldap/ldap.c b/modules/ldap/ldap.c index bb382eb..7935236 100644 --- a/modules/ldap/ldap.c +++ b/modules/ldap/ldap.c @@ -74,3 +74,4 @@ struct ldap_db { -static struct ldap_conf def_conf; +static struct ldap_conf dfl_conf; +static char dfl_config_file[] = "/etc/ldap.conf"; static char dfl_positive_reply[] = "OK"; @@ -255,38 +256,71 @@ readconf(struct smap_option const *opt, const char *val, char **errmsg) } - + +#define MKOPT_DEFAULT 0 +#define MKOPT_REUSE 0x01 +#define MKOPT_RESET 0x02 static int -mod_ldap_init(int argc, char **argv) +make_options(struct ldap_conf *conf, int flags, + struct smap_option **ret_options) { - struct smap_option init_option[] = { + static struct smap_option init_option[] = { { SMAP_OPTSTR(config-file), smap_opt_null, - &init_option, 0, readconf }, - { SMAP_OPTSTR(ssl-ca), smap_opt_string, - &def_conf.cacert }, - { SMAP_OPTSTR(tls-ca), smap_opt_string, - &def_conf.cacert }, + (void*)offsetof(struct ldap_conf, config_file) }, + { SMAP_OPTSTR(tls_cacert), smap_opt_string, + (void*)offsetof(struct ldap_conf, cacert) }, + { SMAP_OPTSTR(tls-cacert), smap_opt_string, + (void*)offsetof(struct ldap_conf, cacert) }, { SMAP_OPTSTR(uri), smap_opt_string, - &def_conf.uri }, + (void*)offsetof(struct ldap_conf, uri) }, { SMAP_OPTSTR(base), smap_opt_string, - &def_conf.base }, + (void*)offsetof(struct ldap_conf, base) }, { SMAP_OPTSTR(filter), smap_opt_string, - &def_conf.filter }, + (void*)offsetof(struct ldap_conf, filter) }, { SMAP_OPTSTR(binddn), smap_opt_string, - &def_conf.binddn }, + (void*)offsetof(struct ldap_conf, binddn) }, { SMAP_OPTSTR(bindpw), smap_opt_string, - &def_conf.bindpw }, + (void*)offsetof(struct ldap_conf, bindpw) }, { SMAP_OPTSTR(bindpwfile), smap_opt_string, - &def_conf.bindpwfile }, + (void*)offsetof(struct ldap_conf, bindpwfile) }, { SMAP_OPTSTR(positive-reply), smap_opt_string, - &def_conf.positive_reply }, + (void*)offsetof(struct ldap_conf, positive_reply) }, { SMAP_OPTSTR(negative-reply), smap_opt_string, - &def_conf.negative_reply }, + (void*)offsetof(struct ldap_conf, negative_reply) }, { SMAP_OPTSTR(onerror-reply), smap_opt_string, - &def_conf.onerror_reply }, + (void*)offsetof(struct ldap_conf, onerror_reply) }, { NULL } }; + int i; + struct smap_option *opt; + + if (flags & MKOPT_REUSE) + opt = *ret_options; + else { + opt = malloc(sizeof(init_option)); + if (!opt) + return 1; + *ret_options = opt; + } + memcpy(opt, init_option, sizeof(init_option)); + + if (flags & MKOPT_RESET) + opt->type = smap_opt_string; + for (i = 0; opt[i].name; i++) { + opt[i].data = (char*)conf + (size_t) opt[i].data; + if ((flags & MKOPT_RESET) && i) + opt[i].type = smap_opt_null; + } + + return 0; +} + +static int +mod_ldap_init(int argc, char **argv) +{ + struct smap_option *opt; + int rc; @@ -294,6 +328,10 @@ mod_ldap_init(int argc, char **argv) - if (smap_parseopt(init_option, argc, argv, 0, NULL)) + if (make_options(&dfl_conf, MKOPT_DEFAULT, &opt)) { + smap_error("not enough memory"); return 1; + } - return 0; + rc = smap_parseopt(opt, argc, argv, 0, NULL); + free(opt); + return rc; } @@ -683,39 +721,30 @@ mod_ldap_init_db(const char *dbid, int argc, char **argv) size_t i, j; + struct smap_option *opt; - struct smap_option init_option[] = { - { SMAP_OPTSTR(config-file), smap_opt_null, - &init_option, 0, readconf }, - { SMAP_OPTSTR(ssl-ca), smap_opt_string, - &conf.cacert }, - { SMAP_OPTSTR(tls-ca), smap_opt_string, - &conf.cacert }, - { SMAP_OPTSTR(uri), smap_opt_string, - &conf.uri }, - { SMAP_OPTSTR(base), smap_opt_string, - &conf.base }, - - { SMAP_OPTSTR(filter), smap_opt_string, - &conf.filter }, - - { SMAP_OPTSTR(binddn), smap_opt_string, - &conf.binddn }, - - { SMAP_OPTSTR(bindpw), smap_opt_string, - &conf.bindpw }, - { SMAP_OPTSTR(bindpwfile), smap_opt_string, - &conf.bindpwfile }, - - { SMAP_OPTSTR(positive-reply), smap_opt_string, - &conf.positive_reply }, - { SMAP_OPTSTR(negative-reply), smap_opt_string, - &conf.negative_reply }, - { SMAP_OPTSTR(onerror-reply), smap_opt_string, - &conf.onerror_reply }, - { NULL } - }; + if (!ldap_conf_cpy(&conf, &dfl_conf)) + return NULL; - if (!ldap_conf_cpy(&conf, &def_conf)) + if (make_options(&conf, MKOPT_RESET, &opt)) { + smap_error("not enough memory"); + ldap_conf_free(&conf); + return NULL; + } + + if (smap_parseopt(opt, argc, argv, 0, NULL)) { + ldap_conf_free(&conf); return NULL; + } + + make_options(&conf, MKOPT_REUSE, &opt); + + if (!conf.config_file && access(dfl_config_file, R_OK) == 0) + conf.config_file = strdup(dfl_config_file); + + if (conf.config_file && parse_ldap_conf(conf.config_file, opt)) { + free(opt); + ldap_conf_free(&conf); + } - if (smap_parseopt(init_option, argc, argv, 0, NULL)) { + if (smap_parseopt(opt, argc, argv, 0, NULL)) { + free(opt); ldap_conf_free(&conf); @@ -723,2 +752,3 @@ mod_ldap_init_db(const char *dbid, int argc, char **argv) } + free(opt); |