From e696c786a4a69f44fa3fe6e006bda0884eb9f1db Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Sun, 19 Oct 2025 10:26:14 +0200 Subject: [PATCH] Support setting uid/gid in permissions.yaml --- cmd/safcm/config/permissions.go | 16 ++++++-- cmd/safcm/config/permissions_test.go | 38 ++++++++++++++++++- .../project/permissions-uid-gid/files/both | 0 .../project/permissions-uid-gid/files/gid | 0 .../project/permissions-uid-gid/files/uid | 0 .../permissions-uid-gid/permissions.yaml | 3 ++ remote/sync/files_test.go | 29 ++++++++++++++ 7 files changed, 82 insertions(+), 4 deletions(-) create mode 100644 cmd/safcm/testdata/project/permissions-uid-gid/files/both create mode 100644 cmd/safcm/testdata/project/permissions-uid-gid/files/gid create mode 100644 cmd/safcm/testdata/project/permissions-uid-gid/files/uid create mode 100644 cmd/safcm/testdata/project/permissions-uid-gid/permissions.yaml diff --git a/cmd/safcm/config/permissions.go b/cmd/safcm/config/permissions.go index 3a92aca..b5ef3a7 100644 --- a/cmd/safcm/config/permissions.go +++ b/cmd/safcm/config/permissions.go @@ -43,7 +43,7 @@ func LoadPermissions(group string, files map[string]*safcm.File) error { xs := strings.Fields(x) if len(xs) != 1 && len(xs) != 3 { return fmt.Errorf("%s: invalid line %q "+ - "(expected [ ])", + "(expected [ ])", path, x) } perm, err := strconv.ParseInt(xs[0], 8, 32) @@ -67,8 +67,18 @@ func LoadPermissions(group string, files map[string]*safcm.File) error { } file.Mode = file.Mode.Type() | FullPermToFileMode(int(perm)) if len(xs) == 3 { - file.User = xs[1] - file.Group = xs[2] + uid, err := strconv.Atoi(xs[1]) + if err == nil { + file.Uid = uid + } else { + file.User = xs[1] + } + gid, err := strconv.Atoi(xs[2]) + if err == nil { + file.Gid = gid + } else { + file.Group = xs[2] + } } } diff --git a/cmd/safcm/config/permissions_test.go b/cmd/safcm/config/permissions_test.go index 4a15a15..45ed5a7 100644 --- a/cmd/safcm/config/permissions_test.go +++ b/cmd/safcm/config/permissions_test.go @@ -107,6 +107,42 @@ host3.example.net nil, }, + { + "permissions-uid-gid", + map[string]*safcm.File{ + "/": { + Path: "/", + Mode: fs.ModeDir | 0755, + Uid: -1, + Gid: -1, + }, + "/uid": { + Path: "/uid", + Mode: 0644, + Uid: 42, + Group: "group", + Gid: -1, + Data: []byte(""), + }, + "/gid": { + Path: "/gid", + Mode: 0644, + User: "user", + Uid: -1, + Gid: 42, + Data: []byte(""), + }, + "/both": { + Path: "/both", + Mode: 0644, + Uid: 42, + Gid: 23, + Data: []byte(""), + }, + }, + nil, + }, + { "permissions-invalid-execute", map[string]*safcm.File{ @@ -155,7 +191,7 @@ host3.example.net Data: []byte("nameserver ::1\n"), }, }, - fmt.Errorf("permissions-invalid-line/permissions.yaml: invalid line \"invalid line\" (expected [ ])"), + fmt.Errorf("permissions-invalid-line/permissions.yaml: invalid line \"invalid line\" (expected [ ])"), }, { "permissions-invalid-path", diff --git a/cmd/safcm/testdata/project/permissions-uid-gid/files/both b/cmd/safcm/testdata/project/permissions-uid-gid/files/both new file mode 100644 index 0000000..e69de29 diff --git a/cmd/safcm/testdata/project/permissions-uid-gid/files/gid b/cmd/safcm/testdata/project/permissions-uid-gid/files/gid new file mode 100644 index 0000000..e69de29 diff --git a/cmd/safcm/testdata/project/permissions-uid-gid/files/uid b/cmd/safcm/testdata/project/permissions-uid-gid/files/uid new file mode 100644 index 0000000..e69de29 diff --git a/cmd/safcm/testdata/project/permissions-uid-gid/permissions.yaml b/cmd/safcm/testdata/project/permissions-uid-gid/permissions.yaml new file mode 100644 index 0000000..538e5b7 --- /dev/null +++ b/cmd/safcm/testdata/project/permissions-uid-gid/permissions.yaml @@ -0,0 +1,3 @@ +/uid: 0644 42 group +/gid: 0644 user 42 +/both: 0644 42 23 diff --git a/remote/sync/files_test.go b/remote/sync/files_test.go index 1803e08..adc3f28 100644 --- a/remote/sync/files_test.go +++ b/remote/sync/files_test.go @@ -1057,6 +1057,35 @@ func TestSyncFile(t *testing.T) { }, nil, }, + { + "file: unchanged (non-default uid/gid)", + safcm.MsgSyncReq{}, + &safcm.File{ + Path: "file", + Mode: 0644, + Uid: uid, + Gid: gid, + Data: []byte("content\n"), + OrigGroup: "group", + }, + func() { + ft.CreateFile("file", "content\n", 0644) + }, + false, + []ft.File{ + root, + { + Path: "file", + Mode: 0644, + Data: []byte("content\n"), + }, + }, + safcm.MsgSyncResp{}, + []string{ + `4: files: "file" (group): unchanged`, + }, + nil, + }, { "file: permission", -- 2.49.1