diff options
author | Martin Hedenfal <martinh@cvs.openbsd.org> | 2010-06-15 15:12:55 +0000 |
---|---|---|
committer | Martin Hedenfal <martinh@cvs.openbsd.org> | 2010-06-15 15:12:55 +0000 |
commit | 2bce23f67dde4f001e337389a57400d3de20e053 (patch) | |
tree | adb2e4e34a0f4ed7166255ee7af00052c78da868 | |
parent | ac2467c4c91b5bce0ee1d16c760443914f54fcf2 (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.c | 101 | ||||
-rw-r--r-- | usr.sbin/ldapd/ldapd.h | 12 | ||||
-rw-r--r-- | usr.sbin/ldapd/ldape.c | 70 | ||||
-rw-r--r-- | usr.sbin/ldapd/namespace.c | 30 |
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) { |