Add DN as a virtual ldap attr (#2379)

This commit is contained in:
Firstyear 2023-12-19 15:07:19 +10:00 committed by GitHub
parent a4c44bc5f9
commit 3408816932
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 17 additions and 14 deletions

View file

@ -187,6 +187,7 @@ pub const OAUTH2_SCOPE_READ: &str = "read";
pub const OAUTH2_SCOPE_SUPPLEMENT: &str = "supplement";
pub const LDAP_ATTR_CN: &str = "cn";
pub const LDAP_ATTR_DN: &str = "dn";
pub const LDAP_ATTR_DISPLAY_NAME: &str = "displayname";
pub const LDAP_ATTR_EMAIL_ALTERNATIVE: &str = "emailalternative";
pub const LDAP_ATTR_EMAIL_PRIMARY: &str = "emailprimary";

View file

@ -11,7 +11,7 @@ use scim_proto::*;
use crate::constants::{
ATTR_ACCOUNT_EXPIRE, ATTR_ACCOUNT_VALID_FROM, ATTR_DESCRIPTION, ATTR_DISPLAYNAME,
ATTR_GIDNUMBER, ATTR_LOGINSHELL, ATTR_MAIL, ATTR_MEMBER, ATTR_NAME, ATTR_PASSWORD_IMPORT,
ATTR_SSH_PUBLICKEY, ATTR_UNIX_PASSWORD_IMPORT, ATTR_TOTP_IMPORT
ATTR_SSH_PUBLICKEY, ATTR_TOTP_IMPORT, ATTR_UNIX_PASSWORD_IMPORT,
};
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, ToSchema)]

View file

@ -2402,8 +2402,12 @@ impl Entry<EntryReduced, EntryCommitted> {
.filter_map(|(ldap_a, kani_a)| {
// In some special cases, we may need to transform or rewrite the values.
match ldap_a {
"entrydn" => Some(LdapPartialAttribute {
atype: "entrydn".to_string(),
LDAP_ATTR_DN => Some(LdapPartialAttribute {
atype: LDAP_ATTR_DN.to_string(),
vals: vec![dn.as_bytes().to_vec()],
}),
LDAP_ATTR_ENTRYDN => Some(LdapPartialAttribute {
atype: LDAP_ATTR_ENTRYDN.to_string(),
vals: vec![dn.as_bytes().to_vec()],
}),
LDAP_ATTR_MAIL_PRIMARY | LDAP_ATTR_EMAIL_PRIMARY => {

View file

@ -268,15 +268,7 @@ impl LdapServer {
// NOTE: All req_attrs are lowercase at this point.
let mapped_attrs: BTreeSet<_> = req_attrs
.iter()
.filter_map(|a| {
// EntryDN and DN have special handling in to_ldap in Entry. We don't
// need these here, we know they will be returned as part of the transform.
if a == "entrydn" || a == "dn" {
None
} else {
Some(AttrString::from(ldap_vattr_map(a).unwrap_or(a)))
}
})
.map(|a| AttrString::from(ldap_vattr_map(a).unwrap_or(a)))
.collect();
(Some(mapped_attrs), req_attrs)
@ -564,9 +556,10 @@ pub(crate) fn ldap_all_vattrs() -> Vec<String> {
ATTR_CN.to_string(),
ATTR_EMAIL.to_string(),
ATTR_LDAP_EMAIL_ADDRESS.to_string(),
LDAP_ATTR_DN.to_string(),
LDAP_ATTR_EMAIL_ALTERNATIVE.to_string(),
LDAP_ATTR_EMAIL_PRIMARY.to_string(),
"entrydn".to_string(),
LDAP_ATTR_ENTRYDN.to_string(),
LDAP_ATTR_ENTRYUUID.to_string(),
LDAP_ATTR_KEYS.to_string(),
LDAP_ATTR_MAIL_ALTERNATIVE.to_string(),
@ -588,7 +581,12 @@ pub(crate) fn ldap_vattr_map(input: &str) -> Option<&str> {
//
// LDAP NAME KANI ATTR SOURCE NAME
match input {
ATTR_CN | ATTR_UID => Some(ATTR_NAME),
// EntryDN and DN have special handling in to_ldap in Entry. However, we
// need to map them to "name" so that if the user has requested dn/entrydn
// only, then we still requested at least one attribute from the backend
// allowing the access control tests to take place. Otherwise no entries
// would be returned.
ATTR_CN | ATTR_UID | LDAP_ATTR_ENTRYDN | LDAP_ATTR_DN => Some(ATTR_NAME),
ATTR_GECOS => Some(ATTR_DISPLAYNAME),
ATTR_EMAIL => Some(ATTR_MAIL),
ATTR_LDAP_EMAIL_ADDRESS => Some(ATTR_MAIL),