summaryrefslogtreecommitdiff
path: root/usr.sbin/ldapd/conn.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/conn.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/conn.c')
-rw-r--r--usr.sbin/ldapd/conn.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/usr.sbin/ldapd/conn.c b/usr.sbin/ldapd/conn.c
index e2ed882015e..e36b5192cbb 100644
--- a/usr.sbin/ldapd/conn.c
+++ b/usr.sbin/ldapd/conn.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: conn.c,v 1.9 2012/04/11 08:31:37 deraadt Exp $ */
+/* $OpenBSD: conn.c,v 1.10 2012/06/16 00:08:32 jmatthew Exp $ */
/*
* Copyright (c) 2009, 2010 Martin Hedenfalk <martin@bzero.se>
@@ -261,7 +261,8 @@ conn_accept(int fd, short event, void *data)
return;
addrlen = sizeof(remote_addr);
- afd = accept(fd, (struct sockaddr *)&remote_addr, &addrlen);
+ afd = accept_reserve(fd, (struct sockaddr *)&remote_addr, &addrlen,
+ FD_RESERVE);
if (afd == -1) {
/*
* Pause accept if we are out of file descriptors, or
@@ -345,3 +346,25 @@ conn_by_fd(int fd)
return NULL;
}
+int
+conn_close_any()
+{
+ struct conn *conn;
+
+ /* Close oldest idle connection */
+ TAILQ_FOREACH_REVERSE(conn, &conn_list, conn_list, next) {
+ if (namespace_conn_queue_count(conn) == 0) {
+ conn_close(conn);
+ return 0;
+ }
+ }
+
+ /* Close oldest connection */
+ conn = TAILQ_LAST(&conn_list, conn_list);
+ if (conn != NULL) {
+ conn_close(conn);
+ return 0;
+ }
+
+ return -1;
+}