summaryrefslogtreecommitdiffstats
path: root/server.c
diff options
context:
space:
mode:
authorSimon Rettberg2014-03-18 19:32:40 +0100
committerSimon Rettberg2014-03-18 19:32:40 +0100
commitf0b46f7a343a79d1eeb29c0d45942df646e9cc35 (patch)
tree6969611ee51f412370c1c8b3171b6e9b72b4f551 /server.c
parentFix double free in scan_ldapsearchfilter (diff)
downloadldadp-f0b46f7a343a79d1eeb29c0d45942df646e9cc35.tar.gz
ldadp-f0b46f7a343a79d1eeb29c0d45942df646e9cc35.tar.xz
ldadp-f0b46f7a343a79d1eeb29c0d45942df646e9cc35.zip
First working version with user and group support, login relaying
Diffstat (limited to 'server.c')
-rw-r--r--server.c111
1 files changed, 80 insertions, 31 deletions
diff --git a/server.c b/server.c
index 91f5703..2c3aebe 100644
--- a/server.c
+++ b/server.c
@@ -11,35 +11,19 @@
#include <errno.h>
#include <socket.h>
-#define ADDRLEN 40
-#define BINDLEN 200
-#define PWLEN 40
-#define BASELEN 100
-#define ALIASLEN 40
-
#define AD_PORT 3268
#define MSGID_BIND 1
-typedef struct {
- size_t baseLen;
- char ip[4];
- time_t lastLookup;
- char addr[ADDRLEN];
- char bind[BINDLEN];
- char password[PWLEN];
- char base[BASELEN];
- epoll_server_t con;
-} server_t;
-
#define MAX_SERVERS 10
static server_t *servers = NULL;
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_flush(epoll_server_t * const server);
-static BOOL server_ensureConnected(const int index);
+static BOOL server_ensureConnected(server_t *server);
static void server_ensureSendBuffer(epoll_server_t * const s, const size_t len);
// Generate a message ID for request to AD
@@ -81,13 +65,13 @@ void server_initServers()
printf("%d servers configured.\n", serverCount);
for (i = 0; i < serverCount; ++i) {
printf("%s:\n Bind: %s\n Base: %s\n", servers[i].addr, servers[i].bind, servers[i].base);
- server_ensureConnected(i);
+ server_ensureConnected(&servers[i]);
}
}
// What the proxy calls
-int server_getFromBase(struct string *in)
+server_t *server_getFromBase(struct string *in)
{
int i;
char buffer[TMPLEN];
@@ -97,13 +81,13 @@ int server_getFromBase(struct string *in)
for (i = 0; i < serverCount; ++i) {
if (searchLen < servers[i].baseLen) continue;
if (strcmp(servers[i].base, buffer + (searchLen - servers[i].baseLen)) == 0) {
- return i;
+ return &servers[i];
}
}
- return -1;
+ return NULL;
}
-uint32_t server_searchRequest(int server, struct SearchRequest *req)
+uint32_t server_searchRequest(server_t *server, struct SearchRequest *req)
{
if (!server_ensureConnected(server)) return 0;
const uint32_t msgid = msgId();
@@ -113,11 +97,68 @@ uint32_t server_searchRequest(int server, struct SearchRequest *req)
char *bufoff = buffer + 50;
fmt_ldapsearchrequest(bufoff, req);
fmt_ldapmessage(bufoff - headerLen, msgid, SearchRequest, bodyLen);
- epoll_server_t * const s = &servers[server].con;
+ epoll_server_t * const s = &server->con;
server_send(s, bufoff - headerLen, headerLen + bodyLen, FALSE);
return msgid;
}
+uint32_t server_tryUserBind(server_t *server, struct string *binddn, struct string *password)
+{
+ 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;
+ if (server->lastLookup + 300 < time(NULL)) {
+ sock = helper_connect4(server->addr, AD_PORT, server->ip);
+ if (sock == -1) {
+ printf("[ADB] Could not resolve/connect to AD server %s\n", server->addr);
+ server_free(con);
+ return 0;
+ }
+ } else {
+ sock = socket_tcp4b();
+ if (sock == -1) {
+ printf("[ADB] Could not allocate socket for connection to AD\n");
+ server_free(con);
+ return 0;
+ }
+ if (socket_connect4(sock, server->ip, AD_PORT) == -1) {
+ printf("[ADB] Could not connect to cached IP of %s\n", server->addr);
+ close(sock);
+ 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);
+ server_free(con);
+ return 0;
+ }
+ // Now bind - TODO: SASL (DIGEST-MD5?)
+ const uint32_t id = msgId();
+ const size_t bodyLen = fmt_ldapbindrequeststring(NULL, 3, binddn, password);
+ const size_t headerLen = fmt_ldapmessage(NULL, id, BindRequest, bodyLen);
+ char buffer[bodyLen + 50];
+ char *bufoff = buffer + 50;
+ if (headerLen >= 50) {
+ printf("[ADB] 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);
+ return id;
+}
+
//
// Private stuff
@@ -140,6 +181,7 @@ static server_t *server_create(const char *server)
}
snprintf(servers[serverCount].addr, ADDRLEN, "%s", server);
servers[serverCount].con.fd = -1;
+ servers[serverCount].con.serverData = &servers[serverCount];
return &servers[serverCount++];
}
@@ -149,6 +191,11 @@ static void server_free(epoll_server_t *server)
if (server->fd != -1) close(server->fd);
server->fd = -1;
server->sbPos = server->sbFill = 0;
+ if (server->dynamic) {
+ printf("Freeing Bind-AD-Connection\n");
+ free(server->sendBuffer);
+ free(server);
+ }
}
static void server_callback(void *data, int haveIn, int haveOut, int doCleanup)
@@ -185,9 +232,12 @@ static void server_callback(void *data, int haveIn, int haveOut, int doCleanup)
if (len > server->rbPos) break; // Body not complete
printf("[AD] Received complete reply...\n");
if (proxy_fromServer(server, len) == -1) {
+ if (server->dynamic) {
+ server_free(server);
+ return;
+ }
printf("Error parsing reply from AD.\n");
- server_free(server);
- return;
+ // Let's try to go on with the next message....
}
// Shift remaining buffer contents
if (len == server->rbPos) {
@@ -248,14 +298,13 @@ static void server_flush(epoll_server_t * const server)
server->sbPos = server->sbFill = 0;
}
-static BOOL server_ensureConnected(const int index)
+static BOOL server_ensureConnected(server_t *server)
{
- server_t * const server = &servers[index];
epoll_server_t * const con = &server->con;
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);
+ printf("Connecting to AD '%s'...\n", server->addr);
con->sbPos = con->sbFill = 0;
int sock;
if (server->lastLookup + 300 < time(NULL)) {
@@ -286,9 +335,9 @@ static BOOL server_ensureConnected(const int index)
con->fd = -1;
return FALSE;
}
- // Now bind
+ // Now bind - TODO: SASL (DIGEST-MD5?)
const size_t bodyLen = fmt_ldapbindrequest(NULL, 3, server->bind, server->password);
- const size_t headerLen = fmt_ldapmessage(NULL, MSGID_BIND, BindResponse, bodyLen);
+ const size_t headerLen = fmt_ldapmessage(NULL, MSGID_BIND, BindRequest, bodyLen);
char buffer[bodyLen + 50];
char *bufoff = buffer + 50;
if (headerLen >= 50) {