summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2014-03-17 19:21:35 +0100
committerSimon Rettberg2014-03-17 19:21:35 +0100
commit18af18b35b72834284e079d79fae45a3d642676f (patch)
treeb622d709bb19c06651b4bed884d85aaaae6442df
parentLean and mean initial commit (diff)
downloadldadp-18af18b35b72834284e079d79fae45a3d642676f.tar.gz
ldadp-18af18b35b72834284e079d79fae45a3d642676f.tar.xz
ldadp-18af18b35b72834284e079d79fae45a3d642676f.zip
More progress.. Warning: Contains very ugly temporary hack for uidNumber<->objectSid mapping ;)
-rw-r--r--ldadp.c3
-rw-r--r--proxy.c111
-rw-r--r--server.c39
-rw-r--r--server.h6
-rw-r--r--types.h2
5 files changed, 91 insertions, 70 deletions
diff --git a/ldadp.c b/ldadp.c
index 8afb3bd..0d2f818 100644
--- a/ldadp.c
+++ b/ldadp.c
@@ -73,9 +73,6 @@ static int loadConfig_handler(void *stuff, const char *section, const char *key,
if (strcmp(key, "base") == 0) {
server_setBase(section, value);
}
- if (strcmp(key, "alias") == 0) {
- server_setAlias(section, value);
- }
return 1;
}
diff --git a/proxy.c b/proxy.c
index c627238..ca4dfc1 100644
--- a/proxy.c
+++ b/proxy.c
@@ -40,10 +40,13 @@ typedef struct
static pending_t _pendingRequest[MAXPENDING];
static int _pendingCount = 0;
-static struct string s_shadowAccount, s_user, s_uid, s_sAMAccountName, s_objectSid;
-static struct string s_objectclass, s_homeDirectory, s_gidNumber, s_gecos, s_dn;
+static struct string s_shadowAccount, s_posixAccount, s_user, s_uid, s_sAMAccountName, s_objectSid;
+static struct string s_objectclass, s_homeDirectory, s_gidNumber, s_gecos, s_dn, s_posixGroup;
static struct string s_loginShell, s_uidNumber, s_mail, s_objectCategory, s_memberOf, s_distinguishedName;
+static char osHack[200], osHackNum[12];
+static int osHackLen = 0;
+
//
static int proxy_clientBindRequest(epoll_client_t *client, const unsigned long messageId, const size_t offset, const size_t maxLen);
@@ -51,6 +54,8 @@ static int proxy_serverBindResponse(epoll_server_t *server, const unsigned long
static int proxy_clientSearchRequest(epoll_client_t *client, const unsigned long messageId, const size_t offset, const size_t maxLen);
static int proxy_serverSearchResult(epoll_server_t *server, const unsigned long messageId, const unsigned long type, const size_t offset, const size_t maxLen);
+static int proxy_localSearchRequest(epoll_client_t *client, const unsigned long messageId, const struct SearchRequest *req);
+
//
#define SETSTR(x) s_ ## x.s = #x; s_ ## x.l = strlen( #x )
@@ -60,6 +65,8 @@ void proxy_init()
if (done) return;
done = 1;
SETSTR(shadowAccount);
+ SETSTR(posixAccount);
+ SETSTR(posixGroup);
SETSTR(user);
SETSTR(uid);
SETSTR(sAMAccountName);
@@ -178,10 +185,26 @@ static inline int iequals(struct string *a, struct string *b)
// ---- client to AD replacements
//#define PREF(...) do { pref(spaces, prefix); printf(__VA_ARGS__); } while (0)
+static BOOL request_isUserFilter(struct Filter *filter);
static void request_replaceFilter(struct Filter *filter);
static void request_replaceAdl(struct AttributeDescriptionList **adl, attr_t *attr);
static void request_replaceAttribute(struct string *attribute, struct string *value);
+static BOOL request_isUserFilter(struct Filter *filter)
+{
+ for (; filter != NULL; filter = filter->next) {
+ if (filter->x != NULL && request_isUserFilter(filter->x)) return TRUE;
+ if (filter->type != EQUAL) continue;
+ if (iequals(&filter->ava.desc, &s_objectclass) &&
+ (equals(&filter->ava.value, &s_posixAccount) || equals(&filter->ava.value, &s_shadowAccount))) {
+ return TRUE;
+ } else if (equals(&filter->ava.desc, &s_uid) || equals(&filter->ava.desc, &s_uidNumber)) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
static void request_replaceFilter(struct Filter *filter)
{
for (; filter != NULL; filter = filter->next) {
@@ -205,7 +228,6 @@ static void request_replaceAdl(struct AttributeDescriptionList **adl, attr_t *at
elifSETATTR(gidNumber);
elifSETATTR(gecos);
elifSETATTR(loginShell);
- elifSETATTR(uidNumber);
else request_replaceAttribute(&(*adl)->a, NULL);
if (*adl == NULL) break;
if (next == NULL) adl = &(*adl)->next; // If next is not NULL, we removed an entry, so we don't need to shift
@@ -220,6 +242,15 @@ static void request_replaceAttribute(struct string *attribute, struct string *va
} else if (iequals(attribute, &s_objectclass)) {
if (value == NULL) return;
if (equals(value, &s_shadowAccount)) *value = s_user;
+ else if (equals(value, &s_posixAccount)) *value = s_user;
+ } else if (equals(attribute, &s_uidNumber)) {
+ *attribute = s_objectSid;
+ if (value == NULL) return;
+ uint32_t tmp = 0;
+ for (size_t i = 0; i < value->l; ++i) tmp = tmp * 10 + (value->s[i] - '0');
+ memcpy(osHack + osHackLen, &tmp, 4);
+ value->s = osHack;
+ value->l = osHackLen + 4;
}
}
@@ -236,6 +267,7 @@ static void response_replacePal(struct PartialAttributeList **pal, attr_t *attr)
{
struct string *username = NULL;
struct PartialAttributeList *last = NULL;
+ struct AttributeDescriptionList *lastObjectClass = NULL;
while (*pal != NULL) {
last = *pal;
struct PartialAttributeList *next = NULL;
@@ -257,6 +289,14 @@ static void response_replacePal(struct PartialAttributeList **pal, attr_t *attr)
if (username == NULL && equals(&(*pal)->type, &s_uid)) {
username = &(*pal)->values->a;
}
+ // Map objectClass user back to posixAccount and shadowAccount
+ if (lastObjectClass == NULL && iequals(&(*pal)->type, &s_objectclass)) {
+ BOOL hasUser = FALSE;
+ for (struct AttributeDescriptionList *adl = (*pal)->values; adl != NULL; adl = adl->next) {
+ if (!hasUser && iequals(&adl->a, &s_user)) hasUser = TRUE;
+ if (hasUser && adl->next == NULL) lastObjectClass = adl;
+ }
+ }
pal = &(*pal)->next;
}
if (username != NULL) {
@@ -265,6 +305,13 @@ static void response_replacePal(struct PartialAttributeList **pal, attr_t *attr)
ADDATTR(loginShell, "/bin/bash");
ADDATTR(gidNumber, "1001");
}
+ if (lastObjectClass != NULL) {
+ lastObjectClass->next = calloc(1, sizeof(struct AttributeDescriptionList));
+ lastObjectClass->next->a = s_posixAccount;
+ lastObjectClass = lastObjectClass->next;
+ lastObjectClass->next = calloc(1, sizeof(struct AttributeDescriptionList));
+ lastObjectClass->next->a = s_shadowAccount;
+ }
}
#undef ADDATTR
#undef elifDELATTR
@@ -288,20 +335,17 @@ static void response_replaceAttribute(struct string *attribute, struct string *v
{
if (equals(attribute, &s_sAMAccountName)) {
*attribute = s_uid;
- } else if (iequals(attribute, &s_objectclass)) {
+ } else if (equals(attribute, &s_objectSid)) {
+ *attribute = s_uidNumber;
if (value == NULL) return;
- if (equals(value, &s_user)) *value = s_shadowAccount;
- } else if (
- equals(attribute, &s_dn) ||
- equals(attribute, &s_distinguishedName) ||
- equals(attribute, &s_memberOf) ||
- equals(attribute, &s_objectCategory)
- ) {
- if (value == NULL) return;
- struct string alias;
- if (server_baseToAlias(value, &alias) != -1) {
- *value = alias;
+ if (osHackLen == 0 && value->l > 4) {
+ osHackLen = value->l - 4;
+ memcpy(osHack, value->s, osHackLen);
}
+ int tmp;
+ memcpy(&tmp, value->s + value->l - 4, 4);
+ value->l = snprintf(osHackNum, 10, "%u", tmp);
+ value->s = osHackNum;
}
}
@@ -325,20 +369,26 @@ static struct PartialAttributeList* response_addPal(struct PartialAttributeList
static int proxy_clientSearchRequest(epoll_client_t *client, const unsigned long messageId, const size_t offset, const size_t maxLen)
{
struct SearchRequest req;
- struct string realBase;
const size_t res = scan_ldapsearchrequest(client->readBuffer + offset, client->readBuffer + maxLen, &req);
if (res == 0) return -1;
- const int server = server_aliasToBase(&req.baseObject, &realBase);
+ const int server = server_getFromBase(&req.baseObject);
if (server == -1) {
- printf("scan_ldapsearchrequest: baseObj %.*s unknown.\n", (int)req.baseObject.l, req.baseObject.s);
+ printf("scan_ldapsearchrequest: baseObj '%.*s' unknown.\n", (int)req.baseObject.l, req.baseObject.s);
return -1;
}
- req.baseObject = realBase;
- printf("scan_ldapsearchrequest: baseO: %.*s, scope: %d, derefAliases: %d\n", (int)req.baseObject.l, req.baseObject.s, req.scope, req.derefAliases);
+ printf("scan_ldapsearchrequest: baseObj: %.*s, scope: %d, derefAliases: %d\n", (int)req.baseObject.l, req.baseObject.s, req.scope, req.derefAliases);
+ //
+ if (!request_isUserFilter(req.filter)) {
+ // Handle locally
+ const int ret = proxy_localSearchRequest(client, messageId, &req);
+ free_ldapsearchrequest(&req);
+ return ret;
+ }
//
pending_t *pending = proxy_getFreePendingSlot(client);
if (pending == NULL) {
printf("No more slots for pending requests\n");
+ free_ldapsearchrequest(&req);
return -1;
}
if (req.attributes == NULL) {
@@ -385,10 +435,6 @@ static int proxy_serverSearchResult(epoll_server_t *server, const unsigned long
struct SearchResultEntry sre;
const size_t res = scan_ldapsearchresultentry(server->readBuffer + offset, server->readBuffer + maxLen, &sre);
if (res == 0) return -1;
- struct string alias;
- if (server_baseToAlias(&sre.objectName, &alias) != -1) {
- sre.objectName = alias;
- }
response_replacePal(&sre.attributes, &pending->attr);
bodyLen = fmt_ldapsearchresultentry(NULL, &sre);
if (bodyLen == 0) {
@@ -423,9 +469,17 @@ static int proxy_clientBindRequest(epoll_client_t *client, const unsigned long m
if (res == 0) return -1; // Parsing request failed
const size_t res2 = scan_ldapstring(client->readBuffer + offset + res, client->readBuffer + maxLen, &password);
printf("scan_ldapbindrequest: Consumed %d, version %lu, method %lu, name '%.*s', bindpw: '%.*s'\n", (int)(res + res2), version, method, (int)name.l, name.s, (int)password.l, password.s);
+ //for (int i = 0; i < password.l; ++i) printf("%c(%x)\n", password.s[i], (int)password.s[i]);
char buffer[800];
char *bufoff = buffer + 100;
- const size_t bodyLen = fmt_ldapbindresponse(bufoff, 0, "", "main screen turn on", "");
+ size_t bodyLen;
+ if (strncmp(password.s, "\x08\x0a\x0d\x7fINCORRECT", 13) != 0) { // FIXME: Drexhack!
+ printf("Password OK\n");
+ bodyLen = fmt_ldapbindresponse(bufoff, 0, "", "main screen turn on", "");
+ } else {
+ printf("Password WRONG\n");
+ bodyLen = fmt_ldapbindresponse(bufoff, 49, "", "nix da", "");
+ }
const size_t headerLen = fmt_ldapmessage(NULL, messageId, BindResponse, bodyLen);
if (headerLen > 100) return -1; // Too long - don't care
fmt_ldapmessage(bufoff - headerLen, messageId, BindResponse, bodyLen);
@@ -443,3 +497,10 @@ static int proxy_serverBindResponse(epoll_server_t *server, const unsigned long
return 0;
}
+// ---- Local handling ----
+
+static int proxy_localSearchRequest(epoll_client_t *client, const unsigned long messageId, const struct SearchRequest *req)
+{
+ return -1;
+}
+
diff --git a/server.c b/server.c
index b303e67..91f5703 100644
--- a/server.c
+++ b/server.c
@@ -21,7 +21,6 @@
#define MSGID_BIND 1
typedef struct {
- size_t aliasLen;
size_t baseLen;
char ip[4];
time_t lastLookup;
@@ -29,7 +28,6 @@ typedef struct {
char bind[BINDLEN];
char password[PWLEN];
char base[BASELEN];
- char alias[ALIASLEN];
epoll_server_t con;
} server_t;
@@ -77,59 +75,28 @@ void server_setBase(const char *server, const char *base)
entry->base[entry->baseLen] = '\0';
}
-void server_setAlias(const char *server, const char *alias)
-{
- server_t *entry = server_create(server);
- if (entry == NULL) return;
- if (snprintf(entry->alias, ALIASLEN, "%s", alias) >= ALIASLEN) printf("Warning: SearchBase Alias for %s is too long.\n", server);
- entry->aliasLen = normalize_dn(entry->alias, entry->alias, min(strlen(entry->alias), ALIASLEN - 1));
- entry->alias[entry->aliasLen] = '\0';
-}
-
void server_initServers()
{
int i;
printf("%d servers configured.\n", serverCount);
for (i = 0; i < serverCount; ++i) {
- printf("%s:\n Bind: %s\n Base: %s\n Proxy Alias: %s\n", servers[i].addr, servers[i].bind, servers[i].base, servers[i].alias);
+ printf("%s:\n Bind: %s\n Base: %s\n", servers[i].addr, servers[i].bind, servers[i].base);
server_ensureConnected(i);
}
}
// What the proxy calls
-int server_aliasToBase(struct string *in, struct string *out)
-{
- int i;
- char buffer[TMPLEN];
- const size_t searchLen = normalize_dn(buffer, in->s, min(in->l, TMPLEN - 1));
- buffer[searchLen] = '\0';
- // Now buffer contains the normalized wanted alias. Try to find a match in the server list
- for (i = 0; i < serverCount; ++i) {
- if (searchLen < servers[i].aliasLen) continue;
- if (strcmp(servers[i].alias, buffer + (searchLen - servers[i].aliasLen)) == 0) {
- // Found, handle
- tmpbuffer_format(out, "%.*s%s", (int)(searchLen - servers[i].aliasLen), buffer, servers[i].base);
- return i;
- }
- }
- return -1;
-}
-
-int server_baseToAlias(struct string *in, struct string *out)
+int server_getFromBase(struct string *in)
{
int i;
char buffer[TMPLEN];
const size_t searchLen = normalize_dn(buffer, in->s, min(in->l, TMPLEN - 1));
buffer[searchLen] = '\0';
- // Now buffer contains the normalized wanted base. Try to find a match in the server list
+ // Now buffer contains the normalized wanted bind/domain/whatev. Try to find a match in the server list
for (i = 0; i < serverCount; ++i) {
- printf("Comparing %s (%s) to %s\n", buffer, buffer + (searchLen - servers[i].baseLen), servers[i].base);
if (searchLen < servers[i].baseLen) continue;
if (strcmp(servers[i].base, buffer + (searchLen - servers[i].baseLen)) == 0) {
- // Found, handle
- tmpbuffer_format(out, "%.*s%s", (int)(searchLen - servers[i].baseLen), buffer, servers[i].alias);
- printf("Match, returning %s\n", out->s);
return i;
}
}
diff --git a/server.h b/server.h
index 1463f8a..79a6f4e 100644
--- a/server.h
+++ b/server.h
@@ -12,15 +12,11 @@ void server_setPassword(const char *server, const char *password);
void server_setBase(const char *server, const char *base);
-void server_setAlias(const char *server, const char *alias);
-
void server_initServers();
int server_send(epoll_server_t *server, const char *buffer, size_t len, const BOOL cork);
-int server_aliasToBase(struct string *in, struct string *out);
-
-int server_baseToAlias(struct string *in, struct string *out);
+int server_getFromBase(struct string *in);
uint32_t server_searchRequest(int server, struct SearchRequest *req);
diff --git a/types.h b/types.h
index 058d3df..417baa1 100644
--- a/types.h
+++ b/types.h
@@ -6,7 +6,7 @@
#include <time.h>
#define REQLEN 4000
-#define MAXMSGLEN 10000
+#define MAXMSGLEN 100000
#define BOOL uint8_t
#define TRUE 1