aboutsummaryrefslogtreecommitdiff
path: root/lib/ldapmap.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2012-10-08 17:36:05 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2012-10-08 17:36:05 +0300
commit9b56a5b05db6630a667ad0c9b16ec45a4e52044d (patch)
treeeca8c25be90428656c24f76f68899c22d0091528 /lib/ldapmap.c
parent04f58aaf7a6f27e3b79e8f5ccffeb006db56aeaf (diff)
downloadeclat-9b56a5b05db6630a667ad0c9b16ec45a4e52044d.tar.gz
eclat-9b56a5b05db6630a667ad0c9b16ec45a4e52044d.tar.bz2
Improve LDAP map.
* lib/expand.c: New file. * lib/getans.c: New file. * lib/Makefile.am: Add new files. * lib/ldapmap.c (ldap_map) <passfile,prompt>: New members. (ldapmap_kw) <passfile,prompt>: New keywords. (ldap_map_open): Prompt for undefined credentials if the "prompt" statement is set to true. (ldap_map_get): Use eclat_expand_kw to expand the filter. * lib/libeclat.h (eclat_trimnl,eclat_getans) (eclat_expand_kw): New protos. * lib/map.c (eclat_map_get): Use eclat_expand_kw. * src/eclat.c (read_format): Likewise.
Diffstat (limited to 'lib/ldapmap.c')
-rw-r--r--lib/ldapmap.c106
1 files changed, 80 insertions, 26 deletions
diff --git a/lib/ldapmap.c b/lib/ldapmap.c
index 5829f67..8d687e4 100644
--- a/lib/ldapmap.c
+++ b/lib/ldapmap.c
@@ -19,6 +19,8 @@
#include <ldap.h>
#include <errno.h>
#include <sysexits.h>
+#include <signal.h>
+#include <pwd.h>
enum { tls_no, tls_yes, tls_only };
@@ -28,7 +30,9 @@ struct ldap_map {
char *base;
char *binddn;
char *bindpw;
+ char *passfile;
int tls;
+ int prompt;
char *filter;
char *attr;
int dbg;
@@ -96,6 +100,10 @@ static struct grecs_keyword ldapmap_kw[] = {
"Set bind password",
grecs_type_string, GRECS_DFLT,
NULL, offsetof(struct ldap_map, bindpw) },
+ { "passfile", "filename",
+ "Read bind password from <filename>",
+ grecs_type_string, GRECS_DFLT,
+ NULL, offsetof(struct ldap_map, passfile) },
{ "tls", "arg",
"TLS mode",
grecs_type_string, GRECS_DFLT,
@@ -116,6 +124,10 @@ static struct grecs_keyword ldapmap_kw[] = {
"LDAP version to use",
grecs_type_int, GRECS_DFLT,
NULL, offsetof(struct ldap_map, ldap_version) },
+ { "prompt", NULL,
+ "Prompt for missing credentials",
+ grecs_type_bool, GRECS_DFLT,
+ NULL, offsetof(struct ldap_map, prompt) },
{ NULL }
};
@@ -171,6 +183,7 @@ ldap_map_free(int dbg, void *data)
free(data);
}
+
static void ldap_unbind(LDAP *ld);
@@ -367,7 +380,7 @@ ldap_bind(int dbg, struct ldap_map *map)
return 1;
}
- if (ldap_result(map->ld, msgid, LDAP_MSG_ALL, NULL, &result ) == -1) {
+ if (ldap_result(map->ld, msgid, LDAP_MSG_ALL, NULL, &result) == -1) {
err("ldap_result failed");
return 1;
}
@@ -389,7 +402,7 @@ ldap_bind(int dbg, struct ldap_map *map)
|| refs) {
/* FIXME: Use debug output for that */
debug(dbg, 2, ("ldap_bind: %s (%d)%s",
- ldap_err2string(ec), ec, msgbuf));
+ ldap_err2string(ec), ec, msgbuf));
if (matched && *matched)
debug(dbg, 2, ("matched DN: %s", matched));
@@ -428,7 +441,63 @@ static int
ldap_map_open(int dbg, void *data)
{
struct ldap_map *map = data;
+ char *user = NULL, *p;
+ uid_t uid = getuid();
+ int i = 0;
+ struct passwd *pw;
+ const char *kw[3];
+
+ pw = getpwuid(uid);
+ if (!pw)
+ die(EX_UNAVAILABLE,
+ "cannot determine user name (uid=%lu)",
+ (unsigned long) uid);
+
+ user = grecs_strdup(pw->pw_name);
+
+ kw[0] = NULL;
+
+ if (map->prompt && isatty(0)) {
+ p = eclat_getans("User name", user, 0);
+ free(user);
+ user = p;
+ if (map->binddn) {
+ kw[0] = "user";
+ kw[1] = user;
+ kw[2] = NULL;
+ p = eclat_expand_kw(map->binddn, kw);
+ } else
+ p = grecs_strdup(user);
+ free(map->binddn);
+ map->binddn = p;
+ }
+
+ if (map->passfile) {
+ char *filename = eclat_expand_kw(map->passfile, kw);
+ FILE *fp = fopen(filename, "r");
+ if (!fp)
+ err("cannot open password file %s: %s",
+ filename, strerror(errno));
+ else {
+ char *buf = NULL;
+ size_t size = 0;
+ int rc = grecs_getline(&buf, &size, fp);
+
+ if (rc <= 0)
+ err("error reading password file %s: %s",
+ filename,
+ rc == 0 ? "empty file?" : strerror(errno));
+ else
+ map->bindpw = buf;
+ }
+ fclose(fp);
+ free(filename);
+ }
+ if (!map->bindpw && map->prompt && isatty(0))
+ map->bindpw = eclat_getans("User password", NULL, 1);
+ free(user);
+
map->ld = ldap_connect(dbg, map);
if (!map->ld)
return eclat_map_failure;
@@ -445,15 +514,6 @@ ldap_map_close(int dbg, void *data)
return 0;
}
-static void
-trimnl(char *s)
-{
- size_t len = strlen(s);
- while (len > 0 && s[len-1] == '\n')
- --len;
- s[len] = 0;
-}
-
static int
keycmp(const void *a, const void *b)
{
@@ -489,7 +549,7 @@ get_ldap_attrs(LDAP *ld, LDAPMessage *msg, const char *attr)
char *p = grecs_malloc(values[i]->bv_len + 1);
memcpy(p, values[i]->bv_val, values[i]->bv_len);
p[values[i]->bv_len] = 0;
- trimnl(p);
+ eclat_trimnl(p);
ret[i] = p;
}
@@ -516,27 +576,21 @@ ldap_map_get(int dbg, void *data, const char *key, char **return_value)
ber_int_t msgid;
char *attrs[2];
char **ret;
- const char *kve[3];
+ const char *kwe[3];
struct wordsplit ws;
-
- kve[0] = "key";
- kve[1] = key;
- kve[2] = NULL;
-
- ws.ws_env = kve;
+ char *filter;
- if (wordsplit(map->filter, &ws,
- WRDSF_NOSPLIT | WRDSF_NOCMD |
- WRDSF_ENV | WRDSF_ENV_KV))
- die(EX_SOFTWARE, "error expanding filter: %s",
- wordsplit_strerror(&ws));
+ kwe[0] = "key";
+ kwe[1] = key;
+ kwe[2] = NULL;
+ filter = eclat_expand_kw(map->filter, kwe);
attrs[0] = (char*) map->attr;
attrs[1] = NULL;
rc = ldap_search_ext(map->ld, map->base, LDAP_SCOPE_SUBTREE,
- ws.ws_wordv[0], attrs, 0,
+ filter, attrs, 0,
NULL, NULL, NULL, -1, &msgid);
- wordsplit_free(&ws);
+ free(filter);
if (rc != LDAP_SUCCESS) {
err("ldap_search_ext: %s", ldap_err2string(rc));

Return to:

Send suggestions and report system problems to the System administrator.