diff options
author | Jonathan Matthew <jmatthew@cvs.openbsd.org> | 2012-06-16 00:08:33 +0000 |
---|---|---|
committer | Jonathan Matthew <jmatthew@cvs.openbsd.org> | 2012-06-16 00:08:33 +0000 |
commit | 13e1995d2d480fdedfbd4d24b123246496d85e86 (patch) | |
tree | 5871128642d3205945aded9f753bc11aee4b4ec1 /usr.sbin/ldapd/ldape.c | |
parent | e9e58745c35db60fc74c0f849458bcad5e111207 (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.c | 23 |
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; |