summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Hedenfal <martinh@cvs.openbsd.org>2010-06-15 15:12:55 +0000
committerMartin Hedenfal <martinh@cvs.openbsd.org>2010-06-15 15:12:55 +0000
commit2bce23f67dde4f001e337389a57400d3de20e053 (patch)
treeadb2e4e34a0f4ed7166255ee7af00052c78da868
parentac2467c4c91b5bce0ee1d16c760443914f54fcf2 (diff)
Implement support in the parent to (re-)open database files on behalf of
the unprivileged child over imsg. Part of a larger change that will fix database compaction.
-rw-r--r--usr.sbin/ldapd/ldapd.c101
-rw-r--r--usr.sbin/ldapd/ldapd.h12
-rw-r--r--usr.sbin/ldapd/ldape.c70
-rw-r--r--usr.sbin/ldapd/namespace.c30
4 files changed, 174 insertions, 39 deletions
diff --git a/usr.sbin/ldapd/ldapd.c b/usr.sbin/ldapd/ldapd.c
index d0be869613d..4a0159435c8 100644
--- a/usr.sbin/ldapd/ldapd.c
+++ b/usr.sbin/ldapd/ldapd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldapd.c,v 1.3 2010/06/15 14:43:56 martinh Exp $ */
+/* $OpenBSD: ldapd.c,v 1.4 2010/06/15 15:12:54 martinh Exp $ */
/*
* Copyright (c) 2009, 2010 Martin Hedenfalk <martin@bzero.se>
@@ -36,10 +36,13 @@
#include "ldapd.h"
-void usage(void);
-void ldapd_sig_handler(int fd, short why, void *data);
-void ldapd_sigchld_handler(int sig, short why, void *data);
-void ldapd_dispatch_ldape(int fd, short event, void *ptr);
+void usage(void);
+void ldapd_sig_handler(int fd, short why, void *data);
+void ldapd_sigchld_handler(int sig, short why, void *data);
+void ldapd_dispatch_ldape(int fd, short event, void *ptr);
+static void ldapd_auth_request(struct imsgev *iev, struct imsg *imsg);
+static void ldapd_open_request(struct imsgev *iev, struct imsg *imsg);
+static void ldapd_log_verbose(struct imsg *imsg);
struct ldapd_stats stats;
pid_t ldape_pid;
@@ -285,7 +288,6 @@ ldapd_dispatch_ldape(int fd, short event, void *ptr)
struct imsgbuf *ibuf;
struct imsg imsg;
ssize_t n;
- int verbose;
if (imsg_event_handle(iev, event) != 0)
return;
@@ -300,24 +302,14 @@ ldapd_dispatch_ldape(int fd, short event, void *ptr)
log_debug("ldapd_dispatch_ldape: imsg type %u", imsg.hdr.type);
switch (imsg.hdr.type) {
- case IMSG_LDAPD_AUTH: {
- struct auth_req *areq = imsg.data;
- struct auth_res ares;
-
- log_debug("authenticating [%s]", areq->name);
- ares.ok = auth_userokay(areq->name, NULL, "auth-ldap",
- areq->password);
- ares.fd = areq->fd;
- ares.msgid = areq->msgid;
- bzero(areq, sizeof(*areq));
- imsg_compose(ibuf, IMSG_LDAPD_AUTH_RESULT, 0, 0, -1,
- &ares, sizeof(ares));
- imsg_event_add(iev);
+ case IMSG_LDAPD_AUTH:
+ ldapd_auth_request(iev, &imsg);
break;
- }
case IMSG_CTL_LOG_VERBOSE:
- memcpy(&verbose, imsg.data, sizeof(verbose));
- log_verbose(verbose);
+ ldapd_log_verbose(&imsg);
+ break;
+ case IMSG_LDAPD_OPEN:
+ ldapd_open_request(iev, &imsg);
break;
default:
log_debug("ldapd_dispatch_ldape: unexpected imsg %d",
@@ -329,3 +321,68 @@ ldapd_dispatch_ldape(int fd, short event, void *ptr)
imsg_event_add(iev);
}
+static void
+ldapd_auth_request(struct imsgev *iev, struct imsg *imsg)
+{
+ struct auth_req *areq = imsg->data;
+ struct auth_res ares;
+
+ if (imsg->hdr.len != sizeof(*areq) + IMSG_HEADER_SIZE)
+ fatal("invalid size of auth request");
+
+ /* make sure name and password are null-terminated */
+ areq->name[sizeof(areq->name) - 1] = '\0';
+ areq->password[sizeof(areq->password) - 1] = '\0';
+
+ log_debug("authenticating [%s]", areq->name);
+ ares.ok = auth_userokay(areq->name, NULL, "auth-ldap", areq->password);
+ ares.fd = areq->fd;
+ ares.msgid = areq->msgid;
+ bzero(areq, sizeof(*areq));
+ imsg_compose_event(iev, IMSG_LDAPD_AUTH_RESULT, 0, 0, -1, &ares,
+ sizeof(ares));
+}
+
+static void
+ldapd_log_verbose(struct imsg *imsg)
+{
+ int verbose;
+
+ if (imsg->hdr.len != sizeof(verbose) + IMSG_HEADER_SIZE)
+ fatal("invalid size of log verbose request");
+
+ memcpy(&verbose, imsg->data, sizeof(verbose));
+ log_verbose(verbose);
+}
+
+static void
+ldapd_open_request(struct imsgev *iev, struct imsg *imsg)
+{
+ struct open_req *oreq = imsg->data;
+ int oflags, fd;
+
+ if (imsg->hdr.len != sizeof(*oreq) + IMSG_HEADER_SIZE)
+ fatal("invalid size of open request");
+
+ /* make sure path is null-terminated */
+ oreq->path[MAXPATHLEN] = '\0';
+
+ if (strncmp(oreq->path, DATADIR, strlen(DATADIR)) != 0) {
+ log_warnx("refusing to open file %s", oreq->path);
+ fatal("ldape sent invalid open request");
+ }
+
+ if (oreq->rdonly)
+ oflags = O_RDONLY;
+ else
+ oflags = O_RDWR | O_CREAT | O_APPEND;
+
+ log_debug("opening [%s]", oreq->path);
+ fd = open(oreq->path, oflags | O_NOFOLLOW, 0600);
+ if (fd == -1)
+ log_warn("%s", oreq->path);
+
+ imsg_compose_event(iev, IMSG_LDAPD_OPEN_RESULT, 0, 0, fd, oreq,
+ sizeof(*oreq));
+}
+
diff --git a/usr.sbin/ldapd/ldapd.h b/usr.sbin/ldapd/ldapd.h
index 9aebad24db6..d87fa5797b1 100644
--- a/usr.sbin/ldapd/ldapd.h
+++ b/usr.sbin/ldapd/ldapd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldapd.h,v 1.3 2010/06/11 12:02:03 martinh Exp $ */
+/* $OpenBSD: ldapd.h,v 1.4 2010/06/15 15:12:54 martinh Exp $ */
/*
* Copyright (c) 2009, 2010 Martin Hedenfalk <martin@bzero.se>
@@ -24,6 +24,7 @@
#include <sys/tree.h>
#include <sys/types.h>
#include <sys/uio.h>
+#include <sys/param.h>
#include <event.h>
#include <imsg.h>
@@ -343,6 +344,11 @@ struct auth_res
long long msgid;
};
+struct open_req {
+ char path[MAXPATHLEN+1];
+ unsigned int rdonly;
+};
+
enum imsg_type {
IMSG_NONE,
IMSG_CTL_OK,
@@ -358,6 +364,8 @@ enum imsg_type {
IMSG_LDAPD_AUTH,
IMSG_LDAPD_AUTH_RESULT,
+ IMSG_LDAPD_OPEN,
+ IMSG_LDAPD_OPEN_RESULT,
};
struct ns_stat {
@@ -469,6 +477,8 @@ struct namespace *namespace_new(const char *suffix);
int namespace_open(struct namespace *ns);
int namespace_reopen_data(struct namespace *ns);
int namespace_reopen_indx(struct namespace *ns);
+int namespace_set_data_fd(struct namespace *ns, int fd);
+int namespace_set_indx_fd(struct namespace *ns, int fd);
struct namespace *namespace_init(const char *suffix, const char *dir);
void namespace_close(struct namespace *ns);
void namespace_remove(struct namespace *ns);
diff --git a/usr.sbin/ldapd/ldape.c b/usr.sbin/ldapd/ldape.c
index 6214fd763bf..912255191f6 100644
--- a/usr.sbin/ldapd/ldape.c
+++ b/usr.sbin/ldapd/ldape.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldape.c,v 1.4 2010/06/11 08:27:58 martinh Exp $ */
+/* $OpenBSD: ldape.c,v 1.5 2010/06/15 15:12:54 martinh Exp $ */
/*
* Copyright (c) 2009, 2010 Martin Hedenfalk <martin@bzero.se>
@@ -34,6 +34,8 @@
void ldape_sig_handler(int fd, short why, void *data);
void ldape_dispatch_ldapd(int fd, short event, void *ptr);
+static void ldape_auth_result(struct imsg *imsg);
+static void ldape_open_result(struct imsg *imsg);
int ldap_starttls(struct request *req);
void send_ldap_extended_response(struct conn *conn,
@@ -333,21 +335,12 @@ ldape_dispatch_ldapd(int fd, short event, void *ptr)
break;
switch (imsg.hdr.type) {
- case IMSG_LDAPD_AUTH_RESULT: {
- struct conn *conn;
- struct auth_res *ares;
-
- ares = imsg.data;
- log_debug("authentication on conn %i/%lld = %d",
- ares->fd, ares->msgid, ares->ok);
- conn = conn_by_fd(ares->fd);
- if (conn->bind_req &&
- conn->bind_req->msgid == ares->msgid)
- ldap_bind_continue(conn, ares->ok);
- else
- log_warnx("spurious auth result");
+ case IMSG_LDAPD_AUTH_RESULT:
+ ldape_auth_result(&imsg);
+ break;
+ case IMSG_LDAPD_OPEN_RESULT:
+ ldape_open_result(&imsg);
break;
- }
default:
log_debug("ldape_dispatch_ldapd: unexpected imsg %d",
imsg.hdr.type);
@@ -358,3 +351,50 @@ ldape_dispatch_ldapd(int fd, short event, void *ptr)
imsg_event_add(iev);
}
+static void
+ldape_auth_result(struct imsg *imsg)
+{
+ struct conn *conn;
+ struct auth_res *ares = imsg->data;
+
+ log_debug("authentication on conn %i/%lld = %d", ares->fd, ares->msgid,
+ ares->ok);
+ conn = conn_by_fd(ares->fd);
+ if (conn->bind_req != NULL && conn->bind_req->msgid == ares->msgid)
+ ldap_bind_continue(conn, ares->ok);
+ else
+ log_warnx("spurious auth result");
+}
+
+static void
+ldape_open_result(struct imsg *imsg)
+{
+ struct namespace *ns;
+ struct open_req *oreq = imsg->data;
+
+ if (imsg->hdr.len != sizeof(*oreq) + IMSG_HEADER_SIZE)
+ fatal("invalid size of open result");
+
+ /* make sure path is null-terminated */
+ oreq->path[MAXPATHLEN] = '\0';
+
+ log_debug("open(%s) returned fd %i", oreq->path, imsg->fd);
+
+ TAILQ_FOREACH(ns, &conf->namespaces, next) {
+ if (strcmp(oreq->path, ns->data_path) == 0) {
+ namespace_set_data_fd(ns, imsg->fd);
+ break;
+ }
+ if (strcmp(oreq->path, ns->indx_path) == 0) {
+ namespace_set_indx_fd(ns, imsg->fd);
+ break;
+ }
+ }
+
+ if (ns == NULL) {
+ log_warnx("spurious open result");
+ close(imsg->fd);
+ } else
+ namespace_queue_schedule(ns);
+}
+
diff --git a/usr.sbin/ldapd/namespace.c b/usr.sbin/ldapd/namespace.c
index 1cf20acb41e..250a5985224 100644
--- a/usr.sbin/ldapd/namespace.c
+++ b/usr.sbin/ldapd/namespace.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: namespace.c,v 1.4 2010/06/11 08:45:06 martinh Exp $ */
+/* $OpenBSD: namespace.c,v 1.5 2010/06/15 15:12:54 martinh Exp $ */
/*
* Copyright (c) 2009, 2010 Martin Hedenfalk <martin@bzero.se>
@@ -34,6 +34,8 @@
static struct btval *namespace_find(struct namespace *ns, char *dn);
static void namespace_queue_replay(int fd, short event, void *arg);
+static int namespace_set_fd(struct namespace *ns,
+ struct btree **bt, int fd, unsigned int flags);
struct namespace *
namespace_new(const char *suffix)
@@ -169,6 +171,32 @@ namespace_reopen_indx(struct namespace *ns)
return 0;
}
+static int
+namespace_set_fd(struct namespace *ns, struct btree **bt, int fd,
+ unsigned int flags)
+{
+ log_info("reopening namespace %s (entries)", ns->suffix);
+ btree_close(*bt);
+ if (ns->sync == 0)
+ flags |= BT_NOSYNC;
+ *bt = btree_open_fd(fd, flags);
+ if (*bt == NULL)
+ return -1;
+ return 0;
+}
+
+int
+namespace_set_data_fd(struct namespace *ns, int fd)
+{
+ return namespace_set_fd(ns, &ns->data_db, fd, BT_REVERSEKEY);
+}
+
+int
+namespace_set_indx_fd(struct namespace *ns, int fd)
+{
+ return namespace_set_fd(ns, &ns->indx_db, fd, 0);
+}
+
void
namespace_close(struct namespace *ns)
{