From a85ed3fad85fdafbb82e5e7d8b2808271d54a052 Mon Sep 17 00:00:00 2001 From: Nathan Coad Date: Thu, 11 Jan 2024 16:48:22 +1100 Subject: [PATCH] check ldap group membership when logging in subsequently --- models/ldap.go | 2 +- models/user.go | 55 ++++++++++++++++++++++++++++++++++---------------- 2 files changed, 39 insertions(+), 18 deletions(-) diff --git a/models/ldap.go b/models/ldap.go index 227980f..22c1e30 100644 --- a/models/ldap.go +++ b/models/ldap.go @@ -262,7 +262,7 @@ func LdapGetGroupMembership(username string, password string) ([]string, error) return groups, nil } -// No need to check group memberships, just validate that we can bind successfully +// VerifyLdapCreds validates that we can bind successfully to LDAP with the supplied credentials func VerifyLdapCreds(username string, password string) error { var err error username = CheckUsername(username) diff --git a/models/user.go b/models/user.go index 1c68d64..495ae2c 100644 --- a/models/user.go +++ b/models/user.go @@ -123,7 +123,7 @@ func LoginCheck(username string, password string) (string, error) { if err == sql.ErrNoRows { // check LDAP if enabled if LdapEnabled { - ldapUser, err := LdapLoginCheck(username, password) + ldapUser, err := UserLdapNewLoginCheck(username, password) if err != nil { errString := fmt.Sprintf("LoginCheck error checking LDAP for user : '%s'\n", err) log.Print(errString) @@ -179,6 +179,14 @@ func LoginCheck(username string, password string) (string, error) { return "", errors.New(errString) } else { log.Printf("LoginCheck successfully verified LDAP user\n") + + // confirm that current LDAP group membership matches a group + err := UserLdapGroupVerify(username, password) + + if err != nil { + // No valid group membership + return "", err + } } } else { log.Printf("LoginCheck no need to repeat LDAP bind for new user login\n") @@ -199,7 +207,34 @@ func LoginCheck(username string, password string) (string, error) { } -func LdapLoginCheck(username string, password string) (User, error) { +// UserLdapGroupVerify will check current group membership and generate an error if match is not found in database +func UserLdapGroupVerify(username string, password string) error { + // try to get LDAP group membership + ldapGroups, err := LdapGetGroupMembership(username, password) + if err != nil { + return err + } + + // Compare all roles against the list of user's group membership + groupList, err := GroupList() + if err != nil { + return err + } + + for _, group := range groupList { + for _, lg := range ldapGroups { + if group.LdapDn == lg { + log.Printf("Found match with groupname '%s' and LDAP group DN '%s', user is a member of group ID '%d'\n", group.GroupName, group.LdapDn, group.GroupId) + return nil + } + } + } + + return errors.New("no match between database and ldap group membership") +} + +// UserLdapNewLoginCheck will verify group membership and save User into database +func UserLdapNewLoginCheck(username string, password string) (User, error) { var u User u.UserName = username @@ -214,27 +249,13 @@ func LdapLoginCheck(username string, password string) (User, error) { } // Compare all roles against the list of user's group membership - //roleList, err := QueryRoles() groupList, err := GroupList() if err != nil { return u, err } matchFound := false - /* - for _, role := range roleList { - for _, group := range groups { - if role.LdapGroup == group { - log.Printf("Found match with role '%s' and LDAP group '%s', user is allowed role ID '%d'\n", role.RoleName, role.LdapGroup, role.RoleId) - u.RoleId = role.RoleId - matchFound = true - break - } //else { - //log.Printf("Role '%s' with LDAP group '%s' not match user group '%s'\n", role.RoleName, role.LdapGroup, group) - //} - } - } - */ + for _, group := range groupList { for _, lg := range ldapGroups { if group.LdapDn == lg {