Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UPNDomain check mandates format of ldap userattr #48

Closed
thomashashi opened this issue Apr 15, 2020 · 1 comment
Closed

UPNDomain check mandates format of ldap userattr #48

thomashashi opened this issue Apr 15, 2020 · 1 comment

Comments

@thomashashi
Copy link

The check in

// Verify that the realm on the LDAP config is the same as the identity's
// realm. The UPNDomain denotes the realm on the LDAP config, and the identity
// domain likewise identifies the realm. This is a case sensitive check.
// This covers an edge case where, potentially, there has been drift between the LDAP
// config's realm and the Kerberos realm. In such a case, it prevents a user from
// passing Kerberos authentication, and then extracting group membership, and
// therefore policies, from a separate directory.
if identity.Domain() != ldapCfg.ConfigEntry.UPNDomain {
w.WriteHeader(400)
_, _ = w.Write([]byte(fmt.Sprintf("identity domain of %q doesn't match LDAP upndomain of %q", identity.Domain(), ldapCfg.ConfigEntry.UPNDomain)))
return
}
authenticated = true

mandates that you have upndomain set inauth/kerberos/config/ldap - if left empty, the check on this line fails because the Identity domain (the Kerberos realm of the SPNEGO user authenticating) isn't an empty string.

Further on in

userBindDN, err := ldapClient.GetUserBindDN(ldapCfg.ConfigEntry, ldapConnection, identity.UserName())
we call GetUserBindDN.

That calls

https://github.com/hashicorp/vault/blob/0f1a1b8b26affc9401c094dd567b4a0717df1c01/sdk/helper/ldaputil/client.go#L107

and you either force the LDAP userattr to be userPrincipalName of the form <name>@<upndomain>, or you respect the userattr setting but assume the value is always <name>@<upndomain> (depending on which path you go down),.

This functionally assumes you're always using Microsoft Active Directory (or an LDAP schema that matches it), precluding the use of, for example, an OpenLDAP rfc2703bis schema:

dn: uid=alice,ou=Users,dc=example,dc=local
objectClass: account
objectClass: posixAccount
cn: alice
uid: alice
uidNumber: 10000 
gidNumber: 10000 
homeDirectory: /home/alice
loginShell: /bin/bash
gecos: alice   
description: User account

dn: cn=devs,ou=Groups,dc=example,dc=local
objectClass: posixGroup
cn: devs
gidNumber: 10000
description: Group account
memberUid: alice

The following configuration was used:

vault write auth/kerberos/config \
    [email protected] \
    service_account="vault/vault.example.local"

vault write auth/kerberos/config/ldap \
    binddn="uid=vault,ou=Users,dc=example,dc=local" \
    bindpass="no" \
    groupattr="cn" \
    groupdn="ou=Groups,dc=example,dc=local" \
    groupfilter="(memberUid={{.Username}})" \
    userdn="ou=Users,dc=example,dc=local" \
    userattr="uid" \
    upndomain="EXAMPLE.LOCAL" \
    discoverdn=true \
    url=ldap://ldap.example.local

Potential fixes:

  • Make the Domain == UPNDomain check configurable - users with an ldap schema which does not record the users Kerberos domain could disable it, mindful of the edge case that's trying to protect against
  • Even if you do make that configurable, setting upndomain in the ldaputil helper now assumes that your userattr is called userPrincipalDomain, which may not be the case if you're not using Active Directory as your LDAP.
@thomashashi
Copy link
Author

Closing as duplicate of #44

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant