summaryrefslogtreecommitdiffstats
path: root/proxy.c
diff options
context:
space:
mode:
authorSimon Rettberg2015-02-12 15:08:06 +0100
committerSimon Rettberg2015-02-12 15:08:06 +0100
commitc3a94473055e098a52ef865a4d2942a1a7d8bf7c (patch)
tree44618726d10d9a80c065bd9b9fd88405e0bec90e /proxy.c
parentAdd OpenSSL-Support (Client<->Proxy) (diff)
downloadldadp-c3a94473055e098a52ef865a4d2942a1a7d8bf7c.tar.gz
ldadp-c3a94473055e098a52ef865a4d2942a1a7d8bf7c.tar.xz
ldadp-c3a94473055e098a52ef865a4d2942a1a7d8bf7c.zip
Hack in support for numeric account names
Diffstat (limited to 'proxy.c')
-rw-r--r--proxy.c54
1 files changed, 50 insertions, 4 deletions
diff --git a/proxy.c b/proxy.c
index c888c2f..38f94e9 100644
--- a/proxy.c
+++ b/proxy.c
@@ -22,6 +22,7 @@ typedef struct
BOOL uid;
BOOL uidNumber;
BOOL cn;
+ BOOL realAccount;
// Internal
BOOL hasUser;
} attr_t;
@@ -46,9 +47,41 @@ static int _pendingCount = 0;
static struct string s_shadowAccount, s_posixAccount, s_user, s_uid, s_sAMAccountName, s_objectSid;
static struct string s_objectClass, s_objectclass, s_homeDirectory, s_gidNumber, s_gecos, s_cn, s_dn, s_posixGroup;
static struct string s_loginShell, s_uidNumber, s_mail, s_objectCategory, s_memberOf, s_distinguishedName;
-static struct string s_1001, s_homeMount, s_member, s_memberUid;
+static struct string s_1001, s_homeMount, s_member, s_memberUid, s_realAccount;
static struct string str_ADUSER;
+// HACK
+static BOOL isInt(struct string *value, int start)
+{
+ size_t i;
+ for (i = start; i < value->l; ++i) {
+ if (value->s[i] < '0' || value->s[i] > '9') return FALSE;
+ }
+ return TRUE;
+}
+static void fixUnNumeric(struct string *value)
+{
+ if (value == NULL || value->l < 2) return;
+ if (value->s[0] != 's') return;
+ if (!isInt(value, 1)) return;
+ value->s++;
+ value->l--;
+}
+static void fixNumeric(struct string *value)
+{
+ size_t i;
+ if (value == NULL || value->l < 1 || value->l > 18) return;
+ if (!isInt(value, 0)) return;
+ char *buf = tmpbuffer_get();
+ buf[0] = 's';
+ for (i = 0; i < value->l; ++i) {
+ buf[i+1] = value->s[i];
+ }
+ value->s = buf;
+ value->l++;
+}
+// END HACK
+
//
static BOOL proxy_clientBindRequest(epoll_client_t *client, const unsigned long messageId, const size_t offset, const size_t maxLen);
@@ -90,6 +123,7 @@ void proxy_init()
SETSTR(dn);
SETSTR(member);
SETSTR(memberUid);
+ SETSTR(realAccount);
SETSTR(1001);
// TODO: configurable
str_ADUSER.s = "ad_user";
@@ -303,6 +337,7 @@ static void request_replaceAdl(server_t *server, struct AttributeDescriptionList
elifSETATTR(homeDirectory);
elifSETATTR(gidNumber);
elifSETATTR(gecos);
+ elifSETATTR(realAccount);
elifSETATTR(loginShell);
else request_replaceAttribute(server, &(*adl)->a, NULL, attr);
if (*adl == NULL) break;
@@ -324,6 +359,10 @@ static void request_replaceAttribute(server_t *server, struct string *attribute,
if (equals(attribute, &s_uid)) {
*attribute = s_sAMAccountName;
if (attr) attr->hasUser = TRUE;
+ // If uid is of format s[0-9]+, we assume that it's a numeric account name in AD, as a workaround
+ if (value == NULL) return;
+ fixUnNumeric(value);
+ ////// ###################
} else if (equals(attribute, &s_homeMount)) {
*attribute = s_homeDirectory;
if (attr != NULL) attr->homeMount = TRUE;
@@ -358,6 +397,7 @@ static void response_replacePal(server_t *server, struct PartialAttributeList **
struct string *username = NULL;
struct AttributeDescriptionList *lastObjectClass = NULL;
struct PartialAttributeList *next = NULL;
+ BOOL wasNumeric = FALSE;
while (*pal != NULL) {
BOOL del = FALSE;
if (0) { } // Remove fields we don't want from AD
@@ -390,6 +430,7 @@ static void response_replacePal(server_t *server, struct PartialAttributeList **
// Fetch user name so we can add our fake fields later
if (username == NULL && equals(&(*pal)->type, &s_uid)) {
username = &(*pal)->values->a;
+ if (username->l > 1 && username->s[0] == 's' && isInt(username, 1)) wasNumeric = TRUE;
}
// Map objectClass user back to posixAccount and shadowAccount
if (lastObjectClass == NULL && iequals(&(*pal)->type, &s_objectclass)) {
@@ -408,8 +449,11 @@ static void response_replacePal(server_t *server, struct PartialAttributeList **
ADDATTR(gecos, "%s,,,", user);
ADDATTR(cn, "%s", user);
if (attr->homeMount && server->homeTemplate[0] != '\0') {
+ if (wasNumeric) user++;
ADDATTR(homeMount, server->homeTemplate, user, user, user, user, user, user);
}
+ // Do this here so user++ will have been executed
+ ADDATTR(realAccount, "%s", user);
}
if (lastObjectClass != NULL) {
ADDATTR(loginShell, "/bin/bash");
@@ -444,6 +488,7 @@ static void response_replaceAttribute(server_t *server, struct string *attribute
{
if (equals(attribute, &s_sAMAccountName)) {
*attribute = s_uid;
+ if (value != NULL) fixNumeric(value);
} else if (equals(attribute, &s_objectSid)) {
*attribute = s_uidNumber;
if (value == NULL) return;
@@ -512,7 +557,7 @@ static BOOL proxy_clientSearchRequest(epoll_client_t *client, const unsigned lon
return ret;
}
// Forward
- if (req.sizeLimit == 0 || req.sizeLimit > 500) req.sizeLimit = 500; // TODO: Magic value
+ if (req.sizeLimit == 0 || req.sizeLimit > 20) req.sizeLimit = 20; // TODO: Magic value
pending_t *pending = proxy_getFreePendingSlot(client);
if (pending == NULL) {
printf("No more slots for pending requests\n");
@@ -613,12 +658,13 @@ static BOOL proxy_clientBindRequest(epoll_client_t *client, const unsigned long
bodyLen = fmt_ldapbindresponse(bufoff, success, "", "main screen turn on", "");
} else {
server_t *server = server_getFromBase(&name);
- if (server == NULL || strncmp(password.s, "\x08\x0a\x0d\x7fINCORRECT", 13) == 0) {
+ if (server == NULL || strncmp(password.s, "\x08\x0a\x0d\x7fINCORRECT", 13) == 0 || isInt(&name, 0)) {
// The INCORRECT part is some weird thing I saw pam_ldap do - save the round trip to AD and deny
- printf("Password INCORRECT or binddn unknown\n");
+ printf("Password INCORRECT or binddn unknown or numeric username\n");
bodyLen = fmt_ldapbindresponse(bufoff, invalidCredentials, "", "invalid credentials", "");
} else {
// Seems to be an actual bind - forward to AD - TODO: SASL (DIGEST-MD5?)
+ fixUnNumeric(&name);
pending_t *pending = proxy_getFreePendingSlot(client);
const unsigned long smid = server_tryUserBind(server, &name, &password);
if (pending == NULL || smid == 0) {