summaryrefslogtreecommitdiff
path: root/usr.sbin/ldapd/ldape.c
diff options
context:
space:
mode:
authorJonathan Matthew <jmatthew@cvs.openbsd.org>2012-06-16 00:08:33 +0000
committerJonathan Matthew <jmatthew@cvs.openbsd.org>2012-06-16 00:08:33 +0000
commit13e1995d2d480fdedfbd4d24b123246496d85e86 (patch)
tree5871128642d3205945aded9f753bc11aee4b4ec1 /usr.sbin/ldapd/ldape.c
parente9e58745c35db60fc74c0f849458bcad5e111207 (diff)
Protect against fd exhaustion when reopening database files. Only accept
client or control connections when there are at least 8 fds available, and close a connection before calling imsg_read if it would be unable to accept an fd from the parent process. ok gilles@
Diffstat (limited to 'usr.sbin/ldapd/ldape.c')
-rw-r--r--usr.sbin/ldapd/ldape.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/usr.sbin/ldapd/ldape.c b/usr.sbin/ldapd/ldape.c
index 433bb2ad64f..39397efaa06 100644
--- a/usr.sbin/ldapd/ldape.c
+++ b/usr.sbin/ldapd/ldape.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldape.c,v 1.16 2012/04/11 08:31:37 deraadt Exp $ */
+/* $OpenBSD: ldape.c,v 1.17 2012/06/16 00:08:32 jmatthew Exp $ */
/*
* Copyright (c) 2009, 2010 Martin Hedenfalk <martin@bzero.se>
@@ -37,6 +37,7 @@ static void ldape_auth_result(struct imsg *imsg);
static void ldape_open_result(struct imsg *imsg);
static void ldape_imsgev(struct imsgev *iev, int code,
struct imsg *imsg);
+static void ldape_needfd(struct imsgev *iev);
int ldap_starttls(struct request *req);
void send_ldap_extended_response(struct conn *conn,
@@ -368,7 +369,8 @@ ldape(struct passwd *pw, char *csockpath, int pipe_parent2ldap[2])
/* Initialize parent imsg events. */
if ((iev_ldapd = calloc(1, sizeof(struct imsgev))) == NULL)
fatal("calloc");
- imsgev_init(iev_ldapd, pipe_parent2ldap[1], NULL, ldape_imsgev);
+ imsgev_init(iev_ldapd, pipe_parent2ldap[1], NULL, ldape_imsgev,
+ ldape_needfd);
/* Initialize control socket. */
bzero(&csock, sizeof(csock));
@@ -486,6 +488,23 @@ ldape_imsgev(struct imsgev *iev, int code, struct imsg *imsg)
}
static void
+ldape_needfd(struct imsgev *iev)
+{
+ /* Try to close a control connection first */
+ if (control_close_any(&csock) == 0) {
+ log_warn("closed a control connection");
+ return;
+ }
+
+ if (conn_close_any() == 0) {
+ log_warn("closed a client connection");
+ return;
+ }
+
+ fatal("unable to free an fd");
+}
+
+static void
ldape_auth_result(struct imsg *imsg)
{
struct conn *conn;