diff --git a/internal/controller/supervisorconfig/activedirectoryupstreamwatcher/active_directory_upstream_watcher.go b/internal/controller/supervisorconfig/activedirectoryupstreamwatcher/active_directory_upstream_watcher.go index 6f83699b..46280b21 100644 --- a/internal/controller/supervisorconfig/activedirectoryupstreamwatcher/active_directory_upstream_watcher.go +++ b/internal/controller/supervisorconfig/activedirectoryupstreamwatcher/active_directory_upstream_watcher.go @@ -29,8 +29,21 @@ const ( activeDirectoryControllerName = "active-directory-upstream-observer" // Default values for active directory config. - defaultActiveDirectoryUsernameAttributeName = "sAMAccountName" - defaultActiveDirectoryUIDAttributeName = "objectGUID" + defaultActiveDirectoryUsernameAttributeName = "sAMAccountName" + defaultActiveDirectoryUIDAttributeName = "objectGUID" + defaultActiveDirectoryGroupNameAttributeName = "sAMAccountName" + + // - is a person. + // - is not a computer. + // - is not shown in advanced view only (which would likely mean its a system created service account with advanced permissions). + // - either the sAMAccountName or the mail attribute matches the input username. + // - the sAMAccountType is for a normal user account. + defaultActiveDirectoryUserSearchFilter = "(&(objectClass=person)(!(objectClass=computer))(!(showInAdvancedViewOnly=TRUE))(|(sAMAccountName={})(mail={}))(sAMAccountType=805306368))" + + // - is a group. + // - has a member that matches the DN of the user we successfully logged in as. + // - perform nested group search by default. + defaultActiveDirectoryGroupSearchFilter = "(&(objectClass=group)(member:1.2.840.113556.1.4.1941:={})" ) type activeDirectoryUpstreamGenericLDAPImpl struct { @@ -271,19 +284,34 @@ func (c *activeDirectoryWatcherController) validateUpstream(ctx context.Context, uidAttribute = defaultActiveDirectoryUIDAttributeName } + groupNameAttribute := spec.GroupSearch.Attributes.GroupName + if len(groupNameAttribute) == 0 { + groupNameAttribute = defaultActiveDirectoryGroupNameAttributeName + } + + userSearchFilter := spec.UserSearch.Filter + if len(userSearchFilter) == 0 { + userSearchFilter = defaultActiveDirectoryUserSearchFilter + } + + groupSearchFilter := spec.GroupSearch.Filter + if len(groupSearchFilter) == 0 { + groupSearchFilter = defaultActiveDirectoryGroupSearchFilter + } + config := &upstreamldap.ProviderConfig{ Name: upstream.Name, Host: spec.Host, UserSearch: upstreamldap.UserSearchConfig{ Base: spec.UserSearch.Base, - Filter: spec.UserSearch.Filter, + Filter: userSearchFilter, UsernameAttribute: usernameAttribute, UIDAttribute: uidAttribute, }, GroupSearch: upstreamldap.GroupSearchConfig{ Base: spec.GroupSearch.Base, - Filter: spec.GroupSearch.Filter, - GroupNameAttribute: spec.GroupSearch.Attributes.GroupName, + Filter: groupSearchFilter, + GroupNameAttribute: groupNameAttribute, }, Dialer: c.ldapDialer, } diff --git a/internal/controller/supervisorconfig/activedirectoryupstreamwatcher/active_directory_upstream_watcher_test.go b/internal/controller/supervisorconfig/activedirectoryupstreamwatcher/active_directory_upstream_watcher_test.go index bde2f91c..d05de468 100644 --- a/internal/controller/supervisorconfig/activedirectoryupstreamwatcher/active_directory_upstream_watcher_test.go +++ b/internal/controller/supervisorconfig/activedirectoryupstreamwatcher/active_directory_upstream_watcher_test.go @@ -1157,6 +1157,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) { name: "when the input activedirectoryidentityprovider leaves user attributes blank, provide default values", inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) { upstream.Spec.UserSearch.Attributes = v1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{} + upstream.Spec.UserSearch.Filter = "" + upstream.Spec.GroupSearch.Filter = "" + upstream.Spec.GroupSearch.Attributes = v1alpha1.ActiveDirectoryIdentityProviderGroupSearchAttributes{} })}, inputSecrets: []runtime.Object{validBindUserSecret("4242")}, setupMocks: func(conn *mockldapconn.MockConn) { @@ -1174,14 +1177,14 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) { BindPassword: testBindPassword, UserSearch: upstreamldap.UserSearchConfig{ Base: testUserSearchBase, - Filter: testUserSearchFilter, + Filter: "(&(objectClass=person)(!(objectClass=computer))(!(showInAdvancedViewOnly=TRUE))(|(sAMAccountName={})(mail={}))(sAMAccountType=805306368))", UsernameAttribute: "sAMAccountName", UIDAttribute: "objectGUID", }, GroupSearch: upstreamldap.GroupSearchConfig{ Base: testGroupSearchBase, - Filter: testGroupSearchFilter, - GroupNameAttribute: testGroupNameAttrName, + Filter: "(&(objectClass=group)(member:1.2.840.113556.1.4.1941:={})", + GroupNameAttribute: "sAMAccountName", }, }, },