From c49d469dcd9243d5e3cc4edb8cb01d832b8a0865 Mon Sep 17 00:00:00 2001 From: James Shubin Date: Wed, 25 Jun 2025 05:19:42 -0400 Subject: [PATCH] engine: resources: Work around trailing slash issue in home dir If the user is logged in, and we try to change from /home/james to /home/james/ we'll get the error: usermod: user james is currently used by process ???? and furthermore, it makes no sense to try and make this change since the usermod function won't do anything if you run: usermod --gid james --groups wheel --home /home/james/ james when /etc/passwd has /home/james as the string. --- engine/resources/user.go | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/engine/resources/user.go b/engine/resources/user.go index b68b60d1..42ae2680 100644 --- a/engine/resources/user.go +++ b/engine/resources/user.go @@ -35,6 +35,7 @@ import ( "io" "os/exec" "os/user" + "path/filepath" "sort" "strconv" "strings" @@ -127,6 +128,11 @@ func (obj *UserRes) Validate() error { } } } + + if obj.HomeDir != nil && !strings.HasSuffix(*obj.HomeDir, "/") { + return fmt.Errorf("the HomeDir should end with a slash") + } + return nil } @@ -223,7 +229,21 @@ func (obj *UserRes) CheckApply(ctx context.Context, apply bool) (bool, error) { if obj.GID != nil && int(*obj.GID) != intGID { usercheck = false } - if obj.HomeDir != nil && *obj.HomeDir != usr.HomeDir { + + // The usermod function will error trying to change /home/james + // to /home/james/ when he's logged in, *AND* it won't actually + // update the string in the /etc/passwd file during normal exec + // of the function. To avoid all this cmp these two identically. + cmpHomeDir := func(h1, h2 string) error { + if h1 == h2 { + return nil + } + if filepath.Clean(h1) == filepath.Clean(h2) { + return nil + } + return fmt.Errorf("did not match") + } + if obj.HomeDir != nil && cmpHomeDir(*obj.HomeDir, usr.HomeDir) != nil { usercheck = false } if obj.Shell != nil && *obj.Shell != shell {