mirror of
https://github.com/slackhq/nebula.git
synced 2026-11-15 21:36:52 +01:00
Let a group share the info API too, and serve it on windows
The info API is for other programs on the host, and on unix the only setting between "the user nebula runs as" and "everyone" was a manual chgrp that the next bind undid; on windows it was not served at all, because which accounts a pipe admits had not been decided. The control socket's `group` decides it, and the info API takes the same key. - `local_api.info.group`: the socket is handed to the group at 0660 unless `socket_mode` says otherwise, and a mode that gives a named group nothing is refused with the mode that would - windows: served on a named pipe, the group an ACE on it as on the control pipe; the e2e test's helpers dial unix sockets, so it still skips there - a changed group or mode on a reload is applied to the socket in place Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
613c7e3061
commit
3fb29d6444
7 files changed
+153
-30
No files matched your search
@@ -4,6 +4,7 @@ package localapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/user"
|
||||
"strconv"
|
||||
@@ -142,6 +143,66 @@ func TestControlSocketWithAGroupTrustsTheKernel(t *testing.T) {
|
||||
require.ErrorContains(t, err, "not permitted")
|
||||
}
|
||||
|
||||
// TestInfoAccessFromConfig: a group with no mode is 0660; a mode that gives the group
|
||||
// nothing is refused, with the mode that would; an explicit mode with group bits is
|
||||
// kept as given.
|
||||
func TestInfoAccessFromConfig(t *testing.T) {
|
||||
name, gid := ownGroup(t)
|
||||
load := func(body string) (infoConfig, error) {
|
||||
c := config.NewC(test.NewLogger())
|
||||
require.NoError(t, c.LoadString(body))
|
||||
return infoConfigFrom(c)
|
||||
}
|
||||
section := func(extra string) string {
|
||||
return "local_api:\n info:\n enabled: true\n socket: /run/nebula/info.sock\n" + extra
|
||||
}
|
||||
|
||||
cfg, err := load(section(" group: " + name + "\n"))
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, os.FileMode(0660), cfg.Access.Mode)
|
||||
require.NotNil(t, cfg.Access.Group)
|
||||
assert.Equal(t, gid, cfg.Access.Group.ID)
|
||||
|
||||
cfg, err = load(section(" group: " + name + "\n socket_mode: \"0664\"\n"))
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, os.FileMode(0664), cfg.Access.Mode)
|
||||
|
||||
_, err = load(section(" group: " + name + "\n socket_mode: \"0600\"\n"))
|
||||
require.ErrorContains(t, err, "gives group "+name+" no access")
|
||||
require.ErrorContains(t, err, `"0660"`)
|
||||
|
||||
cfg, err = load(section(""))
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, os.FileMode(0600), cfg.Access.Mode)
|
||||
assert.Nil(t, cfg.Access.Group)
|
||||
}
|
||||
|
||||
// TestSocketIsHandedToTheGroup: the socket is created with the group's gid and the
|
||||
// mode, and a changed group or mode on a reload is applied to the socket in place.
|
||||
func TestSocketIsHandedToTheGroup(t *testing.T) {
|
||||
name, gid := ownGroup(t)
|
||||
group := &Group{Name: name, ID: gid}
|
||||
want, err := strconv.ParseUint(gid, 10, 32)
|
||||
require.NoError(t, err)
|
||||
|
||||
s, path := serveInfo(t, infoRegistry(), 0600)
|
||||
require.NoError(t, s.Rebind(context.Background(), path, Access{Mode: 0660, Group: group}))
|
||||
fi, err := os.Lstat(path)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, os.FileMode(0660), fi.Mode().Perm())
|
||||
assert.Equal(t, uint32(want), socketGroup(t, path))
|
||||
|
||||
status, _ := test.HTTPGet(t, path, "/v1/whoami")
|
||||
assert.Equal(t, http.StatusOK, status, "the same listener is still serving")
|
||||
|
||||
// The mode is the operator's to widen further.
|
||||
require.NoError(t, s.Rebind(context.Background(), path, Access{Mode: 0664, Group: group}))
|
||||
fi, err = os.Lstat(path)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, os.FileMode(0664), fi.Mode().Perm())
|
||||
assert.Equal(t, path, s.Path())
|
||||
}
|
||||
|
||||
// TestRemovingTheGroupHandsTheSocketBack: a reload that drops the group key leaves the
|
||||
// mode the operator set but returns the socket to the daemon's own group, so the old
|
||||
// group's members are no longer admitted. The socket is first handed to a group this
|
||||
|
||||
Reference in new issue
Block a user