summaryrefslogtreecommitdiffstats
path: root/proxy.c
diff options
context:
space:
mode:
authorSimon Rettberg2014-03-19 14:14:06 +0100
committerSimon Rettberg2014-03-19 14:14:06 +0100
commit87a5f72b2eef3beb10ad50bfbd2a131bd278e67b (patch)
tree4e75715308afcd6211f304ee198eea735416a5d9 /proxy.c
parent(Forgot commit) Add fmt_ldapbindrequeststring that takes struct string as arg... (diff)
downloadldadp-87a5f72b2eef3beb10ad50bfbd2a131bd278e67b.tar.gz
ldadp-87a5f72b2eef3beb10ad50bfbd2a131bd278e67b.tar.xz
ldadp-87a5f72b2eef3beb10ad50bfbd2a131bd278e67b.zip
Work
Diffstat (limited to 'proxy.c')
-rw-r--r--proxy.c74
1 files changed, 62 insertions, 12 deletions
diff --git a/proxy.c b/proxy.c
index c396cc7..b49946c 100644
--- a/proxy.c
+++ b/proxy.c
@@ -15,11 +15,14 @@
typedef struct
{
BOOL homeDirectory;
+ BOOL homeMount;
BOOL gidNumber;
BOOL gecos;
BOOL loginShell;
BOOL uid;
BOOL uidNumber;
+ // Internal
+ BOOL hasUser;
} attr_t;
typedef struct
@@ -42,7 +45,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;
+static struct string s_1001, s_homeMount;
static struct string str_ADUSER;
//
@@ -73,6 +76,7 @@ void proxy_init()
SETSTR(objectClass);
SETSTR(objectclass);
SETSTR(homeDirectory);
+ SETSTR(homeMount);
SETSTR(gidNumber);
SETSTR(gecos);
SETSTR(loginShell);
@@ -196,7 +200,7 @@ static BOOL request_isUserFilter(struct Filter *filter);
static BOOL request_getGroupFilter(struct Filter *filter, struct string *wantedGroupName, uint32_t *wantedGroupId);
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);
+static void request_replaceAttribute(server_t *server, struct string *attribute, struct string *value, attr_t *attr);
static BOOL request_isUserFilter(struct Filter *filter)
{
@@ -229,6 +233,11 @@ static BOOL request_isUserFilter(struct Filter *filter)
* This is REALLY cheap. It doesn't really look at the logic operators in the filter as we assume that pam_ldap
* or nss_ldap etc. won't do anything fancy like "!(objectClass=groupAccount)", just simple AND and OR combined
* with EQUAL.
+ * You could actually get real group memberships using the memberOf attributes of the user, and do additional
+ * queries for these groups, but for that to make any sense you'd also have to implement useful permission
+ * handling.... So as all we really want is authentication and optionally mounting a home directory, we pretend
+ * 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)
{
@@ -267,13 +276,13 @@ static void request_replaceFilter(server_t *server, struct Filter *filter)
break;
case PRESENT:
case SUBSTRING:
- request_replaceAttribute(server, &filter->ava.desc, NULL);
+ request_replaceAttribute(server, &filter->ava.desc, NULL, NULL);
break;
case EQUAL:
case GREATEQUAL:
case LESSEQUAL:
case APPROX:
- request_replaceAttribute(server, &filter->ava.desc, &filter->ava.value);
+ request_replaceAttribute(server, &filter->ava.desc, &filter->ava.value, NULL);
break;
default: break;
}
@@ -290,17 +299,29 @@ static void request_replaceAdl(server_t *server, struct AttributeDescriptionList
elifSETATTR(gidNumber);
elifSETATTR(gecos);
elifSETATTR(loginShell);
- else request_replaceAttribute(server, &(*adl)->a, NULL);
+ else request_replaceAttribute(server, &(*adl)->a, NULL, attr);
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
}
+ if (!attr->hasUser) {
+ if (attr->homeDirectory || attr->gecos || attr->homeMount) {
+ struct AttributeDescriptionList *user = calloc(1, sizeof(struct AttributeDescriptionList));
+ user->a = s_sAMAccountName;
+ user->next = *adl;
+ *adl = user;
+ }
+ }
}
#undef elifSETATTR
-static void request_replaceAttribute(server_t *server, struct string *attribute, struct string *value)
+static void request_replaceAttribute(server_t *server, struct string *attribute, struct string *value, attr_t *attr)
{
if (equals(attribute, &s_uid)) {
*attribute = s_sAMAccountName;
+ if (attr) attr->hasUser = TRUE;
+ } else if (equals(attribute, &s_homeMount)) {
+ *attribute = s_homeDirectory;
+ if (attr != NULL) attr->homeMount = TRUE;
} else if (iequals(attribute, &s_objectclass)) {
if (value == NULL) return;
if (equals(value, &s_shadowAccount)) *value = s_user;
@@ -321,6 +342,7 @@ static void request_replaceAttribute(server_t *server, struct string *attribute,
static void response_replacePal(server_t *server, struct PartialAttributeList **pal, attr_t *attr);
static void response_replaceAdl(server_t *server, struct string *type, struct AttributeDescriptionList **adl, attr_t *attr);
static void response_replaceAttribute(server_t *server, struct string *attribute, struct string *value);
+static struct PartialAttributeList* 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) last = response_addPal(last, &s_ ## x, __VA_ARGS__); } while (0)
@@ -333,13 +355,19 @@ static void response_replacePal(server_t *server, struct PartialAttributeList **
while (*pal != NULL) {
last = *pal;
struct PartialAttributeList *next = NULL;
- if (0) { }
- elifDELATTR(homeDirectory);
+ if (0) { } // Remove fields we don't want from AD
elifDELATTR(gidNumber);
elifDELATTR(gecos);
elifDELATTR(loginShell);
elifDELATTR(uidNumber);
elifDELATTR(mail);
+ 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
+ next = response_filterHomeDir(*pal);
+ if (next == NULL) attr->homeMount = FALSE;
+ }
+ // Entry should be removed, free structs
if (next != NULL) {
free_ldapadl((*pal)->values);
free(*pal);
@@ -362,12 +390,18 @@ static void response_replacePal(server_t *server, struct PartialAttributeList **
pal = &(*pal)->next;
}
if (username != NULL) {
- ADDATTR(homeDirectory, "/home/%.*s", (int)username->l, username->s);
- ADDATTR(gecos, "%.*s,,,", (int)username->l, username->s);
- ADDATTR(loginShell, "/bin/bash");
- ADDATTR(gidNumber, "1001");
+ char *user = tmpbuffer_get();
+ snprintf(user, TMPLEN, "%.*s", (int)username->l, username->s);
+ ADDATTR(homeDirectory, "/home/%s", user);
+ ADDATTR(gecos, "%.*s,,,", user);
+ if (attr->homeMount && server->homeTemplate[0] != '\0') {
+ ADDATTR(homeMount, server->homeTemplate, user, user, user, user, user, user);
+ }
}
if (lastObjectClass != NULL) {
+ ADDATTR(loginShell, "/bin/bash");
+ ADDATTR(gidNumber, "1001");
+ // TODO: Nicer
lastObjectClass->next = calloc(1, sizeof(struct AttributeDescriptionList));
lastObjectClass->next->a = s_posixAccount;
lastObjectClass = lastObjectClass->next;
@@ -412,6 +446,22 @@ static void response_replaceAttribute(server_t *server, struct string *attribute
}
}
+static struct PartialAttributeList* response_filterHomeDir(struct PartialAttributeList *pal)
+{
+ for (struct AttributeDescriptionList *adl = pal->values; adl != NULL; adl = pal->values /* sic */) {
+ if (adl->a.l > 2 && adl->a.s[0] == '\\' && adl->a.s[1] == '\\') {
+ for (size_t i = 0; i < adl->a.l; ++i) if (adl->a.s[i] == '\\') *((char*)adl->a.s + i) = '/';
+ free_ldapadl(adl->next);
+ adl->next = NULL;
+ pal->type = s_homeMount;
+ return NULL;
+ }
+ pal->values = adl->next;
+ free(adl);
+ }
+ return pal->next;
+}
+
static struct PartialAttributeList* response_addPal(struct PartialAttributeList *pal, struct string *attribute, const char *format, ...)
{
struct PartialAttributeList *next = malloc(sizeof(struct PartialAttributeList));