diff -ru a/auth-ldap.conf b/auth-ldap.conf --- a/auth-ldap.conf 2007-01-22 10:50:42.000000000 -0800 +++ b/auth-ldap.conf 2009-12-11 20:01:26.479679474 -0800 @@ -47,6 +47,9 @@ #PFTable ips_vpn_users <Group> + # Match full user DN if true, uid only if false + RFC2307bis true + BaseDN "ou=Groups,dc=example,dc=com" SearchFilter "(|(cn=developers)(cn=artists))" MemberAttribute uniqueMember diff -ru a/src/auth-ldap.m b/src/auth-ldap.m --- a/src/auth-ldap.m 2007-01-22 10:50:42.000000000 -0800 +++ b/src/auth-ldap.m 2009-12-12 00:59:08.504557441 -0800 @@ -409,6 +409,7 @@ TREnumerator *entryIter; TRLDAPEntry *entry; TRLDAPGroupConfig *result = nil; + int userNameLength; /* * Groups are loaded into the array in the order that they are listed @@ -426,15 +427,27 @@ /* Error occured, all stop */ if (!ldapEntries) break; - - /* Iterate over the returned entries */ - entryIter = [ldapEntries objectEnumerator]; - while ((entry = [entryIter nextObject]) != nil) { - if ([ldap compareDN: [entry dn] withAttribute: [groupConfig memberAttribute] value: [ldapUser dn]]) { - /* Group match! */ - result = groupConfig; + if ([groupConfig memberRFC2307BIS]) { + /* Iterate over the returned entries */ + entryIter = [ldapEntries objectEnumerator]; + + while ((entry = [entryIter nextObject]) != nil) { + if ([ldap compareDN: [entry dn] withAttribute: [groupConfig memberAttribute] value: [ldapUser dn]]) { + /* Group match! */ + result = groupConfig; + } + } + } else { + /* Iterate over the returned entries */ + entryIter = [ldapEntries objectEnumerator]; + while ((entry = [entryIter nextObject]) != nil) { + if ([ldap compare: [entry dn] withAttribute: [groupConfig memberAttribute] value: [ldapUser rdn]]) { + /* Group match! */ + result = groupConfig; + } } } + [entryIter release]; [ldapEntries release]; if (result) @@ -551,6 +564,7 @@ int ret = OPENVPN_PLUGIN_FUNC_ERROR; username = get_env("username", envp); + LFString *userName=[[LFString alloc]initWithCString: username]; password = get_env("password", envp); remoteAddress = get_env("ifconfig_pool_remote_ip", envp); @@ -568,6 +582,7 @@ /* Find the user record */ ldapUser = find_ldap_user(ldap, ctx->config, username); + [ldapUser setRDN: userName]; if (!ldapUser) { /* No such user. */ [TRLog warning: "LDAP user \"%s\" was not found.", username]; diff -ru a/src/LFAuthLDAPConfig.m b/src/LFAuthLDAPConfig.m --- a/src/LFAuthLDAPConfig.m 2007-01-22 10:50:42.000000000 -0800 +++ b/src/LFAuthLDAPConfig.m 2009-12-11 22:03:36.574555899 -0800 @@ -79,6 +79,7 @@ /* Group Section Variables */ LF_GROUP_MEMBER_ATTRIBUTE, /* Group Membership Attribute */ + LF_GROUP_MEMBER_RFC2307BIS, /* Look for full DN for user in attribute */ /* Misc Shared */ LF_UNKNOWN_OPCODE, /* Unknown Opcode */ @@ -146,6 +147,7 @@ static OpcodeTable GroupSectionVariables[] = { /* name opcode multi required */ { "MemberAttribute", LF_GROUP_MEMBER_ATTRIBUTE, NO, NO }, + { "RFC2307bis", LF_GROUP_MEMBER_RFC2307BIS, NO, NO }, { NULL, 0 } }; @@ -696,12 +698,22 @@ switch(opcodeEntry->opcode) { TRLDAPGroupConfig *config; + BOOL memberRFC2307BIS; case LF_GROUP_MEMBER_ATTRIBUTE: config = [self currentSectionContext]; [config setMemberAttribute: [value string]]; break; + case LF_GROUP_MEMBER_RFC2307BIS: + config = [self currentSectionContext]; + if (![value boolValue: &memberRFC2307BIS]) { + [self errorBoolValue: value]; + return; + } + [config setMemberRFC2307BIS: memberRFC2307BIS]; + break; + case LF_LDAP_BASEDN: config = [self currentSectionContext]; [config setBaseDN: [value string]]; diff -ru a/src/LFLDAPConnection.h b/src/LFLDAPConnection.h --- a/src/LFLDAPConnection.h 2007-01-22 10:50:42.000000000 -0800 +++ b/src/LFLDAPConnection.h 2009-12-11 23:58:06.142562209 -0800 @@ -56,6 +56,7 @@ baseDN: (LFString *) base attributes: (TRArray *) attributes; - (BOOL) compareDN: (LFString *) dn withAttribute: (LFString *) attribute value: (LFString *) value; +- (BOOL) compare: (LFString *) dn withAttribute: (LFString *) attribute value: (LFString *) value; - (BOOL) setReferralEnabled: (BOOL) enabled; - (BOOL) setTLSCACertFile: (LFString *) fileName; diff -ru a/src/LFLDAPConnection.m b/src/LFLDAPConnection.m --- a/src/LFLDAPConnection.m 2007-03-22 13:09:51.000000000 -0700 +++ b/src/LFLDAPConnection.m 2009-12-11 23:58:23.385560604 -0800 @@ -405,6 +405,50 @@ return NO; } +- (BOOL) compare: (LFString *) dn withAttribute: (LFString *) attribute value: (LFString *) value { + struct timeval timeout; + LDAPMessage *res; + struct berval bval; + int err; + int msgid; + + /* Set up the ber structure for our value */ + bval.bv_val = (char *) [value cString]; + bval.bv_len = [value length] - 1; /* Length includes NULL terminator */ + + /* Set up the timeout */ + timeout.tv_sec = _timeout; + timeout.tv_usec = 0; + + /* Perform the compare */ + if ((err = ldap_compare_ext(ldapConn, [dn cString], [attribute cString], &bval, NULL, NULL, &msgid)) != LDAP_SUCCESS) { + [TRLog debug: "LDAP compare failed: %d: %s", err, ldap_err2string(err)]; + return NO; + } + + /* Wait for the result */ + if (ldap_result(ldapConn, msgid, 1, &timeout, &res) == -1) { + err = ldap_get_errno(ldapConn); + if (err == LDAP_TIMEOUT) + ldap_abandon_ext(ldapConn, msgid, NULL, NULL); + + [TRLog debug: "ldap_compare_ext failed: %s", ldap_err2string(err)]; + return NO; + } + + /* Check the result */ + if (ldap_parse_result(ldapConn, res, &err, NULL, NULL, NULL, NULL, 1) != LDAP_SUCCESS) { + /* Parsing failed */ + return NO; + } + if (err == LDAP_COMPARE_TRUE) + return YES; + else + return NO; + + return NO; +} + - (BOOL) _setLDAPOption: (int) opt value: (const char *) value connection: (LDAP *) ldapConn { int err; diff -ru a/src/TRLDAPEntry.h b/src/TRLDAPEntry.h --- a/src/TRLDAPEntry.h 2006-07-25 16:55:47.000000000 -0700 +++ b/src/TRLDAPEntry.h 2009-12-12 00:40:42.341604016 -0800 @@ -40,11 +40,14 @@ @interface TRLDAPEntry : TRObject { LFString *_dn; + LFString *_rdn; TRHash *_attributes; } - (id) initWithDN: (LFString *) dn attributes: (TRHash *) attributes; - (LFString *) dn; +- (LFString *) rdn; +- (void) setRDN: (LFString *) rdn; - (TRHash *) attributes; @end diff -ru a/src/TRLDAPEntry.m b/src/TRLDAPEntry.m --- a/src/TRLDAPEntry.m 2006-07-25 16:55:47.000000000 -0700 +++ b/src/TRLDAPEntry.m 2009-12-12 00:41:39.356680522 -0800 @@ -42,6 +42,7 @@ return self; _dn = [dn retain]; + _rdn = nil; _attributes = [attributes retain]; return self; @@ -49,6 +50,7 @@ - (void) dealloc { [_dn release]; + [_rdn release]; [_attributes release]; [super dealloc]; } @@ -57,6 +59,14 @@ return _dn; } +- (LFString *) rdn { + return _rdn; +} + +- (void) setRDN: (LFString *) rdn { + _rdn=rdn; +} + - (TRHash *) attributes { return _attributes; } diff -ru a/src/TRLDAPGroupConfig.h b/src/TRLDAPGroupConfig.h --- a/src/TRLDAPGroupConfig.h 2006-07-30 13:19:54.000000000 -0700 +++ b/src/TRLDAPGroupConfig.h 2009-12-11 21:57:07.801558856 -0800 @@ -42,6 +42,7 @@ LFString *_baseDN; LFString *_searchFilter; LFString *_memberAttribute; + BOOL _memberRFC2307BIS; LFString *_pfTable; } @@ -54,6 +55,9 @@ - (LFString *) memberAttribute; - (void) setMemberAttribute: (LFString *) memberAttribute; +- (BOOL) memberRFC2307BIS; +- (void) setMemberRFC2307BIS: (BOOL) memberRFC2307BIS; + - (LFString *) pfTable; - (void) setPFTable: (LFString *) tableName; diff -ru a/src/TRLDAPGroupConfig.m b/src/TRLDAPGroupConfig.m --- a/src/TRLDAPGroupConfig.m 2006-07-30 13:19:54.000000000 -0700 +++ b/src/TRLDAPGroupConfig.m 2009-12-11 21:56:37.308554987 -0800 @@ -81,6 +81,14 @@ _memberAttribute = [memberAttribute retain]; } +- (BOOL) memberRFC2307BIS { + return (_memberRFC2307BIS); +} + +- (void) setMemberRFC2307BIS: (BOOL) memberRFC2307BIS { + _memberRFC2307BIS = memberRFC2307BIS; +} + - (void) setPFTable: (LFString *) tableName { if (_pfTable) [_pfTable release];