49 lines
1.8 KiB
Go
49 lines
1.8 KiB
Go
package launch
|
|
|
|
import (
|
|
"errors"
|
|
"os/exec"
|
|
"os/user"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// novox/hq ADR 0259 §8: a module naming an account of its own runs as it, never as root or the operator.
|
|
func TestABundleRunsAsTheAccountItNamesAndNeverRootOrTheOperator(t *testing.T) {
|
|
was := lookupUser
|
|
t.Cleanup(func() { lookupUser = was })
|
|
lookupUser = func(name string) (*user.User, error) {
|
|
switch name {
|
|
case "telegram":
|
|
return &user.User{Username: "telegram", Uid: "961", Gid: "961", HomeDir: "/var/lib/telegram"}, nil
|
|
case "root":
|
|
return &user.User{Username: "root", Uid: "0", Gid: "0", HomeDir: "/root"}, nil
|
|
case "toor":
|
|
return &user.User{Username: "toor", Uid: "0", Gid: "0", HomeDir: "/root"}, nil
|
|
}
|
|
return nil, errors.New("unknown user")
|
|
}
|
|
cmd := exec.Command("/bin/true")
|
|
cmd.Env = []string{"HOME=/root", "PATH=/usr/bin"}
|
|
if err := runAs(cmd, []string{RunAs + "=telegram", OperatorAccount + "=jo"}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if c := cmd.SysProcAttr.Credential; c == nil || c.Uid != 961 || c.Gid != 961 {
|
|
t.Fatalf("not started as telegram: %+v", cmd.SysProcAttr)
|
|
}
|
|
if env := strings.Join(cmd.Env, " "); !strings.Contains(env, "HOME=/var/lib/telegram") || strings.Contains(env, "HOME=/root") {
|
|
t.Fatalf("the account's home is not its own: %s", env)
|
|
}
|
|
for name, want := range map[string]string{"jo": "operator's account", "root": "names root", "toor": "names root",
|
|
"nobody-here": "does not have"} {
|
|
err := runAs(exec.Command("/bin/true"), []string{RunAs + "=" + name, OperatorAccount + "=jo"})
|
|
if err == nil || !strings.Contains(err.Error(), want) {
|
|
t.Errorf("%s: %v, want a refusal saying %q", name, err, want)
|
|
}
|
|
}
|
|
plain := exec.Command("/bin/true")
|
|
if err := runAs(plain, nil); err != nil || plain.SysProcAttr != nil {
|
|
t.Error("a bundle naming no account was changed")
|
|
}
|
|
}
|