summaryrefslogtreecommitdiffstats
path: root/proxy.c
diff options
context:
space:
mode:
authorSimon Rettberg2014-03-17 19:21:35 +0100
committerSimon Rettberg2014-03-17 19:21:35 +0100
commit18af18b35b72834284e079d79fae45a3d642676f (patch)
treeb622d709bb19c06651b4bed884d85aaaae6442df /proxy.c
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 ;)
Diffstat (limited to 'proxy.c')
-rw-r--r--proxy.c111
1 files changed, 86 insertions, 25 deletions
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;
+}
+