68 lines
2.6 KiB
Go
68 lines
2.6 KiB
Go
package apply
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strconv"
|
|
"testing"
|
|
|
|
"github.com/novox/mesh-host/internal/store"
|
|
)
|
|
|
|
// Below a person's or an agent's home, a directory is that account's (novox/hq issue 339): root's, or another
|
|
// account's, there is one the account does not control in a tree whose every parent it does — and a container
|
|
// mounting one the engine refused is refused with it.
|
|
func TestBelowAHomeOnlyThatAccountsDirectoryIsPlaced(t *testing.T) {
|
|
dir := t.TempDir()
|
|
home := filepath.Join(dir, "home", "alice")
|
|
if err := os.MkdirAll(home, 0o755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
// A uid of its own, never the test's: the build seat runs tests as root, and root's home is no person's.
|
|
const alice = 4242
|
|
passwd := filepath.Join(dir, "passwd")
|
|
if err := os.WriteFile(passwd, fmt.Appendf(nil, "root:x:0:0::/root:/bin/sh\nalice:x:%d:%d::%s:/bin/sh\n",
|
|
alice, alice, home), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
before := passwdFile
|
|
passwdFile = passwd
|
|
t.Cleanup(func() { passwdFile = before })
|
|
|
|
_, _, err := applyOnce(t, `{"id":"notes.data","type":"directory","path":"`+home+`/.config/autostart"}`, nil, store.State{})
|
|
refusedFor339(t, "root's directory below alice's home", err)
|
|
_, _, err = applyOnce(t, `{"id":"notes.data","type":"directory","path":"`+home+`/.config/autostart",`+
|
|
`"owner":"`+strconv.Itoa(alice+1)+`"}`, nil, store.State{})
|
|
refusedFor339(t, "another account's directory below alice's home", err)
|
|
if _, err := os.Stat(filepath.Join(home, ".config")); err == nil {
|
|
t.Fatal("a refused directory's parent was made")
|
|
}
|
|
// Alice's own is placed (judged, not applied: a chown to her needs root).
|
|
if err := refusePath(home+"/.config/notes", placingDirectory, "notes", strconv.Itoa(alice)+":"+strconv.Itoa(alice)); err != nil {
|
|
t.Fatalf("alice's own directory: %v", err)
|
|
}
|
|
// A container mounting a refused directory is refused with it, and not run.
|
|
ran := false
|
|
run := func(ctx context.Context, name string, args ...string) (string, error) {
|
|
switch args[0] {
|
|
case "info":
|
|
return "27.0\n", nil
|
|
case "container":
|
|
return "", os.ErrNotExist
|
|
case "run":
|
|
ran = true
|
|
}
|
|
return "", nil
|
|
}
|
|
_, _, err = Apply(context.Background(), archHost(t), parseTrusted(t, `{"declaration":1,"resources":[
|
|
{"id":"notes.data","type":"directory","path":"`+home+`/.ssh"},
|
|
{"id":"notes.server","type":"container","name":"notes","image":"`+pinned+`","volumes":["`+home+`/.ssh:/keys"]}
|
|
]}`), store.State{}, store.OriginCarried, run, nil, nil)
|
|
refusedFor339(t, "a container mounting a refused directory", err)
|
|
if ran {
|
|
t.Fatal("a container mounting a refused directory was run")
|
|
}
|
|
}
|