outposts/ldap: allow custom attributes to shadow built-in attributes

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2021-09-21 21:59:39 +02:00
parent ae07f13a87
commit 1f97420207
3 changed files with 57 additions and 84 deletions

View file

@ -181,99 +181,45 @@ func (pi *ProviderInstance) Search(req SearchRequest) (ldap.ServerSearchResult,
} }
func (pi *ProviderInstance) UserEntry(u api.User) *ldap.Entry { func (pi *ProviderInstance) UserEntry(u api.User) *ldap.Entry {
attrs := []*ldap.EntryAttribute{
{
Name: "cn",
Values: []string{u.Username},
},
{
Name: "sAMAccountName",
Values: []string{u.Username},
},
{
Name: "uid",
Values: []string{u.Uid},
},
{
Name: "name",
Values: []string{u.Name},
},
{
Name: "displayName",
Values: []string{u.Name},
},
{
Name: "mail",
Values: []string{*u.Email},
},
{
Name: "objectClass",
Values: []string{UserObjectClass, "organizationalPerson", "goauthentik.io/ldap/user"},
},
{
Name: "uidNumber",
Values: []string{pi.GetUidNumber(u)},
},
{
Name: "gidNumber",
Values: []string{pi.GetUidNumber(u)},
},
}
attrs = append(attrs, &ldap.EntryAttribute{Name: "memberOf", Values: pi.GroupsForUser(u)})
// Old fields for backwards compatibility
attrs = append(attrs, &ldap.EntryAttribute{Name: "accountStatus", Values: []string{BoolToString(*u.IsActive)}})
attrs = append(attrs, &ldap.EntryAttribute{Name: "superuser", Values: []string{BoolToString(u.IsSuperuser)}})
attrs = append(attrs, &ldap.EntryAttribute{Name: "goauthentik.io/ldap/active", Values: []string{BoolToString(*u.IsActive)}})
attrs = append(attrs, &ldap.EntryAttribute{Name: "goauthentik.io/ldap/superuser", Values: []string{BoolToString(u.IsSuperuser)}})
attrs = append(attrs, AKAttrsToLDAP(u.Attributes)...)
dn := pi.GetUserDN(u.Username) dn := pi.GetUserDN(u.Username)
attrs := AKAttrsToLDAP(u.Attributes)
attrs = pi.ensureAttributes(attrs, map[string][]string{
"memberOf": pi.GroupsForUser(u),
// Old fields for backwards compatibility
"accountStatus": {BoolToString(*u.IsActive)},
"superuser": {BoolToString(u.IsSuperuser)},
"goauthentik.io/ldap/active": {BoolToString(*u.IsActive)},
"goauthentik.io/ldap/superuser": {BoolToString(u.IsSuperuser)},
"cn": {u.Username},
"sAMAccountName": {u.Username},
"uid": {u.Uid},
"name": {u.Name},
"displayName": {u.Name},
"mail": {*u.Email},
"objectClass": {UserObjectClass, "organizationalPerson", "goauthentik.io/ldap/user"},
"uidNumber": {pi.GetUidNumber(u)},
"gidNumber": {pi.GetUidNumber(u)},
})
return &ldap.Entry{DN: dn, Attributes: attrs} return &ldap.Entry{DN: dn, Attributes: attrs}
} }
func (pi *ProviderInstance) GroupEntry(g LDAPGroup) *ldap.Entry { func (pi *ProviderInstance) GroupEntry(g LDAPGroup) *ldap.Entry {
attrs := []*ldap.EntryAttribute{ attrs := AKAttrsToLDAP(g.akAttributes)
{
Name: "cn",
Values: []string{g.cn},
},
{
Name: "uid",
Values: []string{g.uid},
},
{
Name: "sAMAccountName",
Values: []string{g.cn},
},
{
Name: "gidNumber",
Values: []string{g.gidNumber},
},
}
objectClass := []string{GroupObjectClass, "goauthentik.io/ldap/group"}
if g.isVirtualGroup { if g.isVirtualGroup {
attrs = append(attrs, &ldap.EntryAttribute{ objectClass = []string{GroupObjectClass, "goauthentik.io/ldap/group", "goauthentik.io/ldap/virtual-group"}
Name: "objectClass",
Values: []string{GroupObjectClass, "goauthentik.io/ldap/group", "goauthentik.io/ldap/virtual-group"},
})
} else {
attrs = append(attrs, &ldap.EntryAttribute{
Name: "objectClass",
Values: []string{GroupObjectClass, "goauthentik.io/ldap/group"},
})
}
attrs = append(attrs, &ldap.EntryAttribute{Name: "member", Values: g.member})
attrs = append(attrs, &ldap.EntryAttribute{Name: "goauthentik.io/ldap/superuser", Values: []string{BoolToString(g.isSuperuser)}})
if g.akAttributes != nil {
attrs = append(attrs, AKAttrsToLDAP(g.akAttributes)...)
} }
attrs = pi.ensureAttributes(attrs, map[string][]string{
"objectClass": objectClass,
"member": g.member,
"goauthentik.io/ldap/superuser": {BoolToString(g.isSuperuser)},
"cn": {g.cn},
"uid": {g.uid},
"sAMAccountName": {g.cn},
"gidNumber": {g.gidNumber},
})
return &ldap.Entry{DN: g.dn, Attributes: attrs} return &ldap.Entry{DN: g.dn, Attributes: attrs}
} }

View file

@ -140,3 +140,26 @@ func (pi *ProviderInstance) GetRIDForGroup(uid string) int32 {
return int32(gid) return int32(gid)
} }
func (pi *ProviderInstance) ensureAttributes(attrs []*ldap.EntryAttribute, shouldHave map[string][]string) []*ldap.EntryAttribute {
for name, values := range shouldHave {
attrs = pi.mustHaveAttribute(attrs, name, values)
}
return attrs
}
func (pi *ProviderInstance) mustHaveAttribute(attrs []*ldap.EntryAttribute, name string, value []string) []*ldap.EntryAttribute {
shouldSet := false
for _, attr := range attrs {
if attr.Name == name {
shouldSet = true
}
}
if shouldSet {
return append(attrs, &ldap.EntryAttribute{
Name: name,
Values: value,
})
}
return attrs
}

View file

@ -64,6 +64,10 @@ The virtual groups gidNumber is equal to the uidNumber of the user.
**Additionally**, for both users and (non-virtual) groups, any attributes you set are also present as LDAP Attributes. **Additionally**, for both users and (non-virtual) groups, any attributes you set are also present as LDAP Attributes.
:::info
Starting with 2021.9.1, custom attributes will override the inbuilt attributes.
:::
## SSL ## SSL
You can also configure SSL for your LDAP Providers by selecting a certificate and a server name in the provider settings. You can also configure SSL for your LDAP Providers by selecting a certificate and a server name in the provider settings.