diff --git a/changelog/29118.txt b/changelog/29118.txt new file mode 100644 index 000000000000..39295ca98a54 --- /dev/null +++ b/changelog/29118.txt @@ -0,0 +1,3 @@ +```release-note:improvement +auth/ldap: Adds an option to enable sAMAccountname logins when upndomain is set. +``` diff --git a/sdk/helper/ldaputil/config.go b/sdk/helper/ldaputil/config.go index 9044b19fdaa1..c84ab42a6cdd 100644 --- a/sdk/helper/ldaputil/config.go +++ b/sdk/helper/ldaputil/config.go @@ -256,6 +256,11 @@ Default: ({{.UserAttr}}={{.Username}})`, Description: "If set to a value greater than 0, the LDAP backend will use the LDAP server's paged search control to request pages of up to the given size. This can be used to avoid hitting the LDAP server's maximum result size limit. Otherwise, the LDAP backend will not use the paged search control.", Default: 0, }, + "enable_samaccountname_login": { + Type: framework.TypeBool, + Description: "If true, matching sAMAccountName attribute values will be allowed to login when upndomain is defined.", + Default: false, + }, } } @@ -434,6 +439,10 @@ func NewConfigEntry(existing *ConfigEntry, d *framework.FieldData) (*ConfigEntry cfg.MaximumPageSize = d.Get("max_page_size").(int) } + if _, ok := d.Raw["enable_samaccountname_login"]; ok || !hadExisting { + cfg.EnableSamaccountnameLogin = d.Get("enable_samaccountname_login").(bool) + } + return cfg, nil } @@ -468,9 +477,10 @@ type ConfigEntry struct { // where the tag was being ignored, causing it to be jsonified as "CaseSensitiveNames", etc. // To continue reading in users' previously stored values, // we chose to carry that forward. - CaseSensitiveNames *bool `json:"CaseSensitiveNames,omitempty"` - ClientTLSCert string `json:"ClientTLSCert"` - ClientTLSKey string `json:"ClientTLSKey"` + CaseSensitiveNames *bool `json:"CaseSensitiveNames,omitempty"` + ClientTLSCert string `json:"ClientTLSCert"` + ClientTLSKey string `json:"ClientTLSKey"` + EnableSamaccountnameLogin bool `json:"EnableSamaccountnameLogin"` } func (c *ConfigEntry) Map() map[string]interface{} { @@ -481,29 +491,30 @@ func (c *ConfigEntry) Map() map[string]interface{} { func (c *ConfigEntry) PasswordlessMap() map[string]interface{} { m := map[string]interface{}{ - "url": c.Url, - "userdn": c.UserDN, - "groupdn": c.GroupDN, - "groupfilter": c.GroupFilter, - "groupattr": c.GroupAttr, - "userfilter": c.UserFilter, - "upndomain": c.UPNDomain, - "userattr": c.UserAttr, - "certificate": c.Certificate, - "insecure_tls": c.InsecureTLS, - "starttls": c.StartTLS, - "binddn": c.BindDN, - "deny_null_bind": c.DenyNullBind, - "discoverdn": c.DiscoverDN, - "tls_min_version": c.TLSMinVersion, - "tls_max_version": c.TLSMaxVersion, - "use_token_groups": c.UseTokenGroups, - "anonymous_group_search": c.AnonymousGroupSearch, - "request_timeout": c.RequestTimeout, - "connection_timeout": c.ConnectionTimeout, - "username_as_alias": c.UsernameAsAlias, - "dereference_aliases": c.DerefAliases, - "max_page_size": c.MaximumPageSize, + "url": c.Url, + "userdn": c.UserDN, + "groupdn": c.GroupDN, + "groupfilter": c.GroupFilter, + "groupattr": c.GroupAttr, + "userfilter": c.UserFilter, + "upndomain": c.UPNDomain, + "userattr": c.UserAttr, + "certificate": c.Certificate, + "insecure_tls": c.InsecureTLS, + "starttls": c.StartTLS, + "binddn": c.BindDN, + "deny_null_bind": c.DenyNullBind, + "discoverdn": c.DiscoverDN, + "tls_min_version": c.TLSMinVersion, + "tls_max_version": c.TLSMaxVersion, + "use_token_groups": c.UseTokenGroups, + "anonymous_group_search": c.AnonymousGroupSearch, + "request_timeout": c.RequestTimeout, + "connection_timeout": c.ConnectionTimeout, + "username_as_alias": c.UsernameAsAlias, + "dereference_aliases": c.DerefAliases, + "max_page_size": c.MaximumPageSize, + "enable_samaccountname_login": c.EnableSamaccountnameLogin, } if c.CaseSensitiveNames != nil { m["case_sensitive_names"] = *c.CaseSensitiveNames @@ -595,6 +606,7 @@ func ConvertConfig(cfg *ConfigEntry) *capldap.ClientConfig { MaximumPageSize: cfg.MaximumPageSize, DerefAliases: cfg.DerefAliases, DeprecatedVaultPre111GroupCNBehavior: cfg.UsePre111GroupCNBehavior, + EnableSamaccountnameLogin: cfg.EnableSamaccountnameLogin, } if cfg.Certificate != "" { diff --git a/sdk/helper/ldaputil/config_test.go b/sdk/helper/ldaputil/config_test.go index b7fd22ccbb2d..e6aa02fb05c7 100644 --- a/sdk/helper/ldaputil/config_test.go +++ b/sdk/helper/ldaputil/config_test.go @@ -178,6 +178,7 @@ var jsonConfigDefault = []byte(` "max_page_size": 0, "CaseSensitiveNames": false, "ClientTLSCert": "", - "ClientTLSKey": "" + "ClientTLSKey": "", + "enable_samaccountname_login": false } `) diff --git a/website/content/api-docs/auth/ldap.mdx b/website/content/api-docs/auth/ldap.mdx index eec8772318e2..68214847afc2 100644 --- a/website/content/api-docs/auth/ldap.mdx +++ b/website/content/api-docs/auth/ldap.mdx @@ -105,6 +105,9 @@ This endpoint configures the LDAP auth method. paged search control. - `use_token_groups` `(bool: true)` - (Optional) Use the Active Directory tokenGroups constructed attribute of the user to find the group memberships. +- `enable_samaccountname_login` `(bool: false)` - (Optional) If true, Active Directory + LDAP users can login using `sAMAccountName` in addition to the `userPrincipalName` + attribute value when `upndomain` is defined. @include 'tokenfields.mdx' diff --git a/website/content/docs/auth/ldap.mdx b/website/content/docs/auth/ldap.mdx index cead3960ef6f..5673e9fad903 100644 --- a/website/content/docs/auth/ldap.mdx +++ b/website/content/docs/auth/ldap.mdx @@ -144,6 +144,7 @@ For anonymous search, `discoverdn` must be set to `true`, and `deny_null_bind` m #### Binding - user principal name (AD) - `upndomain` (string, optional) - userPrincipalDomain used to construct the UPN string for the authenticating user. The constructed UPN will appear as `[username]@UPNDomain`. Example: `example.com`, which will cause vault to bind as `username@example.com`. +- `enable_samaccountname_login` (bool, optional) - If true, Active Directory LDAP users can login using `sAMAccountName` in addition to the `userPrincipalName` attribute value when `upndomain` is defined. ### Group membership resolution