summaryrefslogtreecommitdiffstats
path: root/server.c
diff options
context:
space:
mode:
authorSimon Rettberg2015-06-26 14:58:03 +0200
committerSimon Rettberg2015-06-26 14:58:03 +0200
commit2e37d6b71692508fa5d2764c1c80f3c7ca7c2894 (patch)
tree7a2e3240c380b9c532fc990dfefc1179eb3a1420 /server.c
parentFix the fix of the fix of SSL (diff)
downloadldadp-2e37d6b71692508fa5d2764c1c80f3c7ca7c2894.tar.gz
ldadp-2e37d6b71692508fa5d2764c1c80f3c7ca7c2894.tar.xz
ldadp-2e37d6b71692508fa5d2764c1c80f3c7ca7c2894.zip
Send search requests on the same connection the explicit bind was done on, so the user's permissions regarding visibility of search results will be applied
Diffstat (limited to 'server.c')
-rw-r--r--server.c99
1 files changed, 50 insertions, 49 deletions
diff --git a/server.c b/server.c
index 91164bb..2fdb601 100644
--- a/server.c
+++ b/server.c
@@ -22,7 +22,6 @@ static int serverCount = 0;
static void server_init();
static server_t *server_create(const char *server);
-static void server_free(epoll_server_t *server);
static void server_callback(void *data, int haveIn, int haveOut, int doCleanup);
static void server_haveIn(epoll_server_t *server);
static void server_haveOut(epoll_server_t * const server);
@@ -171,6 +170,12 @@ server_t *server_getFromBase(struct string *in)
uint32_t server_searchRequest(server_t *server, struct SearchRequest *req)
{
if (!server_ensureConnected(server)) return 0;
+ epoll_server_t * const s = &server->con;
+ return server_searchRequestOnConnection(s, req);
+}
+
+uint32_t server_searchRequestOnConnection(epoll_server_t *server, struct SearchRequest *req)
+{
const uint32_t msgid = msgId();
const size_t bodyLen = fmt_ldapsearchrequest(NULL, req);
const size_t headerLen = fmt_ldapmessage(NULL, msgid, SearchRequest, bodyLen);
@@ -178,36 +183,35 @@ uint32_t server_searchRequest(server_t *server, struct SearchRequest *req)
char *bufoff = buffer + 50;
fmt_ldapsearchrequest(bufoff, req);
fmt_ldapmessage(bufoff - headerLen, msgid, SearchRequest, bodyLen);
- epoll_server_t * const s = &server->con;
- server_send(s, bufoff - headerLen, headerLen + bodyLen, FALSE);
+ server_send(server, bufoff - headerLen, headerLen + bodyLen, FALSE);
return msgid;
}
-uint32_t server_tryUserBind(server_t *server, struct string *binddn, struct string *password)
+uint32_t server_tryUserBind(server_t *server, struct string *binddn, struct string *password, epoll_server_t **newcon)
{
epoll_server_t *con = calloc(1, sizeof(epoll_server_t));
con->serverData = server;
con->fd = -1;
con->bound = FALSE;
con->dynamic = TRUE;
- printf("Connecting to AD '%s' for %.*ss bind...\n", server->addr, (int)binddn->l, binddn->s);
con->sbPos = con->sbFill = 0;
int sock = server_connectInternal(server);
if (sock == -1) {
+ printf("[Proxy] Could not connect to AD for user bind.\n");
server_free(con);
return 0;
}
- printf("[ADB] Connected, binding....\n");
helper_nonblock(sock);
con->fd = sock;
con->callback = &server_callback;
if (ePoll_add(EPOLLIN | EPOLLOUT | EPOLLET, (epoll_item_t*)con) == -1) {
- printf("[ADB] epoll_add failed for ad server %s\n", server->addr);
+ printf("[Proxy] epoll_add failed for AD server %s on user bind\n", server->addr);
server_free(con);
return 0;
}
// SSL
if (!server_connectSsl(con)) {
+ printf("[Proxy] SSL handshake failed for AD server %s on user bind\n", server->addr);
server_free(con);
return 0;
}
@@ -218,13 +222,14 @@ uint32_t server_tryUserBind(server_t *server, struct string *binddn, struct stri
char buffer[bodyLen + 50];
char *bufoff = buffer + 50;
if (headerLen >= 50) {
- printf("[ADB] bind too long for %s\n", server->addr);
+ printf("[Proxy] User bind too long for %s\n", server->addr);
server_free(con);
return 0;
}
fmt_ldapbindrequeststring(bufoff, 3, binddn, password);
fmt_ldapmessage(bufoff - headerLen, id, BindRequest, bodyLen);
server_send(con, bufoff - headerLen, bodyLen + headerLen, FALSE);
+ *newcon = con;
return id;
}
@@ -254,8 +259,9 @@ static server_t *server_create(const char *server)
return &servers[serverCount++];
}
-static void server_free(epoll_server_t *server)
+void server_free(epoll_server_t *server)
{
+ proxy_removeServer(server);
server->bound = FALSE;
if (server->ssl != NULL) {
SSL_free(server->ssl);
@@ -267,7 +273,7 @@ static void server_free(epoll_server_t *server)
}
server->sbPos = server->sbFill = 0;
if (server->dynamic) {
- printf("Freeing Bind-AD-Connection\n");
+ //printf("Freeing Bind-AD-Connection\n");
free(server->sendBuffer);
free(server);
}
@@ -276,38 +282,37 @@ static void server_free(epoll_server_t *server)
static void server_callback(void *data, int haveIn, int haveOut, int doCleanup)
{
epoll_server_t *server = (epoll_server_t *)data;
- if (doCleanup || server->kill) {
- server_free(server);
- return;
- }
if (server->ssl == NULL) {
// Plain connection
if (haveIn) server_haveIn(server);
if (haveOut) server_haveOut(server);
- if (server->kill) server_free(server);
- return;
- }
- // SSL
- if (!server->sslConnected) {
- // Still SSL-Connecting
- if (!ssl_connectServer(server)) {
- printf("SSL Server connect failed!\n");
- server_free(server);
- return;
+ } else {
+ // SSL
+ if (!server->sslConnected) {
+ // Still SSL-Connecting
+ if (!ssl_connectServer(server)) {
+ printf("[Proxy] SSL handshake for AD server %s failed.\n", server->serverData->addr);
+ server_free(server);
+ return;
+ }
+ }
+ // The connect above might have succeeded, so check again and start sending/receiving if so
+ if (server->sslConnected) {
+ // Since we don't know if the incoming data is just wrapped application data or ssl protocol stuff, we always call both
+ server_haveIn(server);
+ server_haveOut(server);
}
- if (!server->sslConnected) return;
}
- // Since we don't know if the incoming data is just wrapped application data or ssl protocol stuff, we always call both
- server_haveIn(server);
- server_haveOut(server);
- if (server->kill) server_free(server);
+ if (doCleanup || server->kill) {
+ server_free(server);
+ }
}
static void server_haveIn(epoll_server_t *server)
{
for (;;) {
if (server->rbPos >= MAXMSGLEN) {
- printf("[AD->Proxy] Read buffer overflow. Disconnecting.\n");
+ printf("[Proxy] Buffer overflow while reading from AD server. Disconnecting.\n");
server->kill = TRUE;
return;
}
@@ -316,11 +321,10 @@ static void server_haveIn(epoll_server_t *server)
if (server->ssl == NULL) {
// Plain
ret = read(server->fd, server->readBuffer + server->rbPos, buflen);
- printf("AD read %d (err %d)\n", (int)ret, errno);
if (ret < 0 && errno == EINTR) continue;
if (ret < 0 && errno == EAGAIN) break;
+ if (ret < 0) printf("[Proxy] AD Server %s gone while reading (ret=%d, errno=%d).\n", server->serverData->addr, (int)ret, errno);
if (ret <= 0) {
- printf("AD Server gone while reading.\n");
server->kill = TRUE;
return;
}
@@ -330,7 +334,7 @@ static void server_haveIn(epoll_server_t *server)
if (ret <= 0) {
int err = SSL_get_error(server->ssl, ret);
if (SSL_BLOCKED(err)) break;
- printf("AD Server gone while reading (%d, %d).\n", (int)ret, err);
+ if (err != 0) printf("[Proxy] AD Server %s gone while reading (ret=%d, err=%d).\n", server->serverData->addr, (int)ret, err);
server->kill = TRUE;
return;
}
@@ -343,13 +347,13 @@ static void server_haveIn(epoll_server_t *server)
if (consumed == 0) break; // Length-Header not complete
len += consumed;
if (len > server->rbPos) break; // Body not complete
- printf("[AD] Received complete reply (need %d, have %d)...\n", (int)len, (int)server->rbPos);
+ //printf("[AD] Received complete reply (need %d, have %d)...\n", (int)len, (int)server->rbPos);
if (!proxy_fromServer(server, len)) {
if (server->dynamic) {
server->kill = TRUE;
return;
}
- printf("Error parsing reply from AD.\n");
+ printf("[Proxy] Error parsing message from AD.\n");
// Let's try to go on with the next message....
}
// Shift remaining buffer contents
@@ -370,14 +374,13 @@ BOOL server_send(epoll_server_t *server, const char *buffer, size_t len, const B
// Nothing in send buffer, fire away
const int ret = write(server->fd, buffer, len);
if (ret == 0 || (ret < 0 && errno != EINTR && errno != EAGAIN)) {
- printf("Server gone when trying to send.\n");
+ printf("[Proxy] AD Server %s gone when trying to send.\n", server->serverData->addr);
return FALSE;
}
server->lastActive = time(NULL);
if (ret == (int)len) return TRUE;
// Couldn't send everything, continue with buffering logic below
if (ret > 0) {
- printf("[AD] Partial send (%d of %d)\n", ret, (int)len);
buffer += ret;
len -= (size_t)ret;
}
@@ -405,7 +408,7 @@ static void server_haveOut(epoll_server_t * const server)
if (ret < 0 && errno == EINTR) continue;
if (ret < 0 && errno == EAGAIN) return;
if (ret <= 0) {
- printf("Connection to AD Server failed while flushing (ret: %d, errno: %d)\n", (int)ret, errno);
+ printf("[Proxy] AD Server %s gone while flushing send buffer (ret=%d, errno=%d)\n", server->serverData->addr, (int)ret, errno);
return;
}
} else {
@@ -419,7 +422,7 @@ static void server_haveOut(epoll_server_t * const server)
} else if (err == SSL_ERROR_SSL) {
ssl_printErrors(NULL);
}
- printf("SSL server gone while sending (%d)\n", err);
+ printf("[Proxy] AD Server %s gone while flushing send buffer (ret=%d, err=%d)\n", server->serverData->addr, (int)ret, err);
ERR_print_errors_fp(stdout);
server->kill = TRUE;
return; // Closed
@@ -443,16 +446,14 @@ static BOOL server_ensureConnected(server_t *server)
if (con->fd != -1 && con->lastActive + 120 > time(NULL)) return TRUE;
if (con->fd != -1) close(con->fd);
con->bound = FALSE;
- printf("Connecting to AD '%s'...\n", server->addr);
con->sbPos = con->sbFill = 0;
int sock = server_connectInternal(server);
if (sock == -1) return FALSE;
- printf("Connected, binding....\n");
helper_nonblock(sock);
con->fd = sock;
con->callback = &server_callback;
if (ePoll_add(EPOLLIN | EPOLLOUT | EPOLLET, (epoll_item_t*)con) == -1) {
- printf("epoll_add failed for ad server %s\n", server->addr);
+ printf("[Proxy] epoll_add failed for ad server %s\n", server->addr);
close(con->fd);
con->fd = -1;
return FALSE;
@@ -469,7 +470,7 @@ static BOOL server_ensureConnected(server_t *server)
char buffer[bodyLen + 50];
char *bufoff = buffer + 50;
if (headerLen >= 50) {
- printf("[AD] bind too long for %s\n", server->addr);
+ printf("[Proxy] bind too long for %s\n", server->addr);
close(con->fd);
con->fd = -1;
return FALSE;
@@ -488,7 +489,7 @@ static BOOL server_ensureSendBuffer(epoll_server_t * const s, const size_t len)
}
if (s->sbLen - s->sbFill < len) {
if (s->writeBlocked) {
- printf("SSL Write blocked and buffer to small (%d)\n", (int)s->sbLen);
+ printf("[Proxy] SSL write to AD server blocked and buffer to small (%d bytes)\n", (int)s->sbLen);
return FALSE;
}
if (s->sbPos != 0) {
@@ -512,17 +513,17 @@ static int server_connectInternal(server_t *server)
if (server->lastLookup + 300 < time(NULL)) {
sock = helper_connect4(server->addr, port, server->ip);
if (sock == -1) {
- printf("Could not resolve/connect to AD server %s\n", server->addr);
+ printf("[Proxy] Could not resolve hostname or connect to AD server %s\n", server->addr);
return -1;
}
} else {
sock = socket_tcp4b();
if (sock == -1) {
- printf("Could not allocate socket for connection to AD\n");
+ printf("[Proxy] Could not allocate socket for connection to AD server %s\n", server->addr);
return -1;
}
if (socket_connect4(sock, server->ip, port) == -1) {
- printf("Could not connect to cached IP of %s\n", server->addr);
+ printf("[Proxy] Could not connect to cached IP (%s) of %s\n", server->ip, server->addr);
server->lastLookup = 0;
close(sock);
return -1;
@@ -537,11 +538,11 @@ static BOOL server_connectSsl(epoll_server_t *server)
server->sslConnected = FALSE;
server->ssl = ssl_new(server->fd, server->serverData->sslContext);
if (server->ssl == NULL) {
- printf("Could not get SSL client from context\n");
+ printf("[Proxy] Could not get SSL client from context\n");
return FALSE;
}
if (!ssl_connectServer(server)) {
- printf("SSL connect failed.\n");
+ printf("[Proxy] SSL connect to AD server %s failed.\n", server->serverData->addr);
SSL_free(server->ssl);
server->ssl = NULL;
return FALSE;