diff --git a/lib/srv/usermgmt.go b/lib/srv/usermgmt.go index 66168eb013005..8714665f76929 100644 --- a/lib/srv/usermgmt.go +++ b/lib/srv/usermgmt.go @@ -675,6 +675,7 @@ func (u *HostUserManagement) getHostUser(username string) (*HostUser, error) { group, err := u.backend.LookupGroupByID(gid) if err != nil { groupErrs = append(groupErrs, err) + continue } groups[group.Name] = struct{}{} diff --git a/lib/srv/usermgmt_test.go b/lib/srv/usermgmt_test.go index 1a1908e0f431d..f88f48fe93cf1 100644 --- a/lib/srv/usermgmt_test.go +++ b/lib/srv/usermgmt_test.go @@ -52,6 +52,7 @@ type testHostUserBackend struct { setUserGroupsCalls int createHomeDirectoryCalls int + groupDatabaseErr error } func newTestUserMgmt() *testHostUserBackend { @@ -95,6 +96,10 @@ func (tm *testHostUserBackend) LookupGroup(groupname string) (*user.Group, error } func (tm *testHostUserBackend) LookupGroupByID(gid string) (*user.Group, error) { + if tm.groupDatabaseErr != nil { + return nil, tm.groupDatabaseErr + } + for groupName, groupGid := range tm.groups { if groupGid == gid { return &user.Group{ @@ -1105,3 +1110,28 @@ func TestHostUsersResolveGroups(t *testing.T) { }) } } + +// errors fetching groups related to a user should not cause panics during UpsertUser +func TestRegressionGroupErrorDoesNotPanic(t *testing.T) { + t.Parallel() + + allGroups := []string{"foo", "bar", "baz"} + users, backend := initBackend(t, allGroups) + + userinfo := services.HostUsersInfo{ + Groups: slices.Clone(allGroups[:2]), + Mode: services.HostUserModeKeep, + } + + // Create user + closer, err := users.UpsertUser("alice", userinfo) + assert.NoError(t, err) + assert.Equal(t, nil, closer) + assert.Zero(t, backend.setUserGroupsCalls) + assert.ElementsMatch(t, append(userinfo.Groups, types.TeleportKeepGroup), backend.users["alice"]) + assert.NotContains(t, backend.users["alice"], types.TeleportDropGroup) + + backend.groupDatabaseErr = errors.New("could not find group") + _, err = users.UpsertUser("alice", userinfo) + require.Error(t, err) +}