summaryrefslogtreecommitdiffstats
path: root/proxy.c
diff options
context:
space:
mode:
authorSimon Rettberg2014-05-26 19:56:09 +0200
committerSimon Rettberg2014-05-26 19:56:09 +0200
commit3b6608506bb7a5519ef4e270e261176a5801f750 (patch)
tree5bc004958559960bee49248342bb3d87a105229b /proxy.c
parentupdated config example (diff)
downloadldadp-3b6608506bb7a5519ef4e270e261176a5801f750.tar.gz
ldadp-3b6608506bb7a5519ef4e270e261176a5801f750.tar.xz
ldadp-3b6608506bb7a5519ef4e270e261176a5801f750.zip
Support more AD attributes
Diffstat (limited to 'proxy.c')
-rw-r--r--proxy.c39
1 files changed, 27 insertions, 12 deletions
diff --git a/proxy.c b/proxy.c
index e6709a4..5bd9541 100644
--- a/proxy.c
+++ b/proxy.c
@@ -21,6 +21,7 @@ typedef struct
BOOL loginShell;
BOOL uid;
BOOL uidNumber;
+ BOOL cn;
// Internal
BOOL hasUser;
} attr_t;
@@ -45,7 +46,7 @@ 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;
+static struct string s_1001, s_homeMount, s_member, s_memberUid;
static struct string str_ADUSER;
//
@@ -87,6 +88,8 @@ void proxy_init()
SETSTR(distinguishedName);
SETSTR(cn);
SETSTR(dn);
+ SETSTR(member);
+ SETSTR(memberUid);
SETSTR(1001);
// TODO: configurable
str_ADUSER.s = "ad_user";
@@ -197,7 +200,7 @@ static inline int iequals(struct string *a, struct string *b)
//#define PREF(...) do { pref(spaces, prefix); printf(__VA_ARGS__); } while (0)
static BOOL request_isUserFilter(struct Filter *filter);
-static BOOL request_getGroupFilter(struct Filter *filter, struct string *wantedGroupName, uint32_t *wantedGroupId);
+static BOOL request_getGroupFilter(struct Filter *filter, struct string *wantedGroupName, uint32_t *wantedGroupId, BOOL *wantsMember);
static void request_replaceFilter(server_t *server, struct Filter *filter);
static void request_replaceAdl(server_t *server, struct AttributeDescriptionList **adl, attr_t *attr);
static void request_replaceAttribute(server_t *server, struct string *attribute, struct string *value, attr_t *attr);
@@ -239,14 +242,14 @@ static BOOL request_isUserFilter(struct Filter *filter)
* there is just one group with id 1001 and name ad_user.
* This function will try to figure out if the given filter is a lookup for a group name or group id.
*/
-static BOOL request_getGroupFilter(struct Filter *filter, struct string *wantedGroupName, uint32_t *wantedGroupId)
+static BOOL request_getGroupFilter(struct Filter *filter, struct string *wantedGroupName, uint32_t *wantedGroupId, BOOL *wantsMember)
{
BOOL retval = FALSE;
for (; filter != NULL; filter = filter->next) {
switch (filter->type) {
case AND:
case OR:
- if (filter->x != NULL && request_getGroupFilter(filter->x, wantedGroupName, wantedGroupId)) retval = TRUE;
+ if (filter->x != NULL && request_getGroupFilter(filter->x, wantedGroupName, wantedGroupId, wantsMember)) retval = TRUE;
break;
case EQUAL:
case APPROX:
@@ -257,6 +260,8 @@ static BOOL request_getGroupFilter(struct Filter *filter, struct string *wantedG
for (size_t i = 0; i < filter->ava.value.l; ++i) *wantedGroupId = (*wantedGroupId * 10) + (filter->ava.value.s[i] - '0');
} else if (equals(&filter->ava.desc, &s_cn)) {
*wantedGroupName = filter->ava.value;
+ } else if (equals(&filter->ava.desc, &s_member) || equals(&filter->ava.desc, &s_memberUid)) {
+ *wantsMember = TRUE;
}
break;
default: break;
@@ -346,7 +351,8 @@ static BOOL response_filterHomeDir(struct PartialAttributeList *pal);
static struct PartialAttributeList* response_addPal(struct PartialAttributeList *pal, struct string *attribute, const char *format, ...);
#define ADDATTR(x,...) do { if (attr->x) *pal = response_addPal(*pal, &s_ ## x, __VA_ARGS__); } while (0)
-#define elifDELATTR(x) else if (equals(&(*pal)->type, &s_ ## x)) next = (*pal)->next, del = TRUE
+#define elifDELATTR(x) else if (equals(&(*pal)->type, &s_ ## x)) next = (*pal)->next, del = TRUE, attr->x = TRUE
+#define elifDEL(x) else if (equals(&(*pal)->type, &s_ ## x)) next = (*pal)->next, del = TRUE
static void response_replacePal(server_t *server, struct PartialAttributeList **pal, attr_t *attr)
{
struct string *username = NULL;
@@ -359,14 +365,18 @@ static void response_replacePal(server_t *server, struct PartialAttributeList **
elifDELATTR(gecos);
elifDELATTR(loginShell);
elifDELATTR(uidNumber);
- elifDELATTR(mail);
+ elifDEL(mail);
+ elifDELATTR(cn);
+ elifDEL(memberOf);
else if (equals(&(*pal)->type, &s_homeDirectory)) {
// homeDirectory is set in AD - it can either be a local path (in which case it's useless)
// or a UNC path, which we can easily mount via mount.cifs
- if (response_filterHomeDir(*pal)) {
+ if (!response_filterHomeDir(*pal)) {
del = TRUE;
- attr->homeMount = FALSE;
+ attr->homeMount = TRUE;
next = (*pal)->next;
+ } else {
+ attr->homeMount = FALSE;
}
}
// Entry should be removed, free structs
@@ -396,6 +406,7 @@ static void response_replacePal(server_t *server, struct PartialAttributeList **
snprintf(user, TMPLEN, "%.*s", (int)username->l, username->s);
ADDATTR(homeDirectory, "/home/%s", user);
ADDATTR(gecos, "%s,,,", user);
+ ADDATTR(cn, "%s", user);
if (attr->homeMount && server->homeTemplate[0] != '\0') {
ADDATTR(homeMount, server->homeTemplate, user, user, user, user, user, user);
}
@@ -456,12 +467,12 @@ static BOOL response_filterHomeDir(struct PartialAttributeList *pal)
free_ldapadl(adl->next);
adl->next = NULL;
pal->type = s_homeMount;
- return FALSE;
+ return TRUE;
}
pal->values = adl->next;
free(adl);
}
- return TRUE;
+ return FALSE;
}
static struct PartialAttributeList* response_addPal(struct PartialAttributeList *pal, struct string *attribute, const char *format, ...)
@@ -655,10 +666,11 @@ static int proxy_localSearchRequest(epoll_client_t *client, const unsigned long
{
struct string name;
uint32_t number = 2;
+ BOOL wantsMember = FALSE;
name.l = 0;
- if (request_getGroupFilter(req->filter, &name, &number)) {
+ if (request_getGroupFilter(req->filter, &name, &number, &wantsMember)) {
// Request for group (by number or by name)?
- if (number == 2 && name.l == 0) {
+ if (number == 2 && name.l == 0 && !wantsMember) {
// posixGroup requested, but neither gidNumber nor cn requested, so it must be "list all"
number = 1001;
name.l = 1;
@@ -668,6 +680,7 @@ static int proxy_localSearchRequest(epoll_client_t *client, const unsigned long
}
if (number == 1001 || name.l != 0) {
// At least one of them was set
+ printf("Sending fake group membership\n");
// TODO: Helper for setting this stuff up
struct SearchResultEntry sre;
struct PartialAttributeList gidNumber, cn, objectClass;
@@ -706,6 +719,8 @@ static int proxy_localSearchRequest(epoll_client_t *client, const unsigned long
fmt_ldapmessage(buffer, messageId, SearchResultEntry, bodyLen);
fmt_ldapsearchresultentry(buffer + headerLen, &sre);
client_send(client, buffer, headerLen + bodyLen, TRUE);
+ } else {
+ printf("Sending empty posixGroup search result.\n");
}
const size_t doneLen = fmt_ldapsearchresultdone(NULL, success, "", "", "");
const size_t doneHeaderLen = fmt_ldapmessage(NULL, messageId, SearchResultDone, doneLen);