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.
This commit is contained in:
James Shubin
2025-06-25 05:19:42 -04:00
parent 0a79daf277
commit c49d469dcd

View File

@@ -35,6 +35,7 @@ import (
"io" "io"
"os/exec" "os/exec"
"os/user" "os/user"
"path/filepath"
"sort" "sort"
"strconv" "strconv"
"strings" "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 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 { if obj.GID != nil && int(*obj.GID) != intGID {
usercheck = false 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 usercheck = false
} }
if obj.Shell != nil && *obj.Shell != shell { if obj.Shell != nil && *obj.Shell != shell {