From 3b6608506bb7a5519ef4e270e261176a5801f750 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 26 May 2014 19:56:09 +0200 Subject: Support more AD attributes --- proxy.c | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) (limited to 'proxy.c') 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); -- cgit v1.2.3-55-g7522