|
|
@@ -118,10 +118,14 @@ func isAdministrator() bool {
|
|
|
}
|
|
|
|
|
|
// sddlFor grants full access to the account nebula is running as, to SYSTEM and to
|
|
|
-// Administrators, and read and write, which is what a client's connect takes, to the
|
|
|
-// group acc names, if any; nobody else. P makes the DACL protected, so it does not
|
|
|
-// inherit entries that would widen it. It is dockerd's descriptor for its pipe, with
|
|
|
-// its -G group in the same place.
|
|
|
+// Administrators, and to the group acc names, if any, what a client's connect takes
|
|
|
+// and no more; nobody else. P makes the DACL protected, so it does not inherit entries
|
|
|
+// that would widen it. It is dockerd's descriptor for its pipe, with its -G group in the
|
|
|
+// same place, except for the group's mask: dockerd grants GENERIC_READ|GENERIC_WRITE,
|
|
|
+// and on a pipe GENERIC_WRITE carries FILE_CREATE_PIPE_INSTANCE, which would let a
|
|
|
+// member create further instances under the name and answer other clients itself. The
|
|
|
+// mask here is FILE_GENERIC_READ|FILE_GENERIC_WRITE with that right left out, which
|
|
|
+// opens the pipe and reads and writes it and nothing else.
|
|
|
//
|
|
|
// Administrators is the counterpart of the uid 0 allowance in the unix peer check. The
|
|
|
// service normally runs as LocalSystem, so without it an operator in an elevated shell
|
|
|
@@ -137,11 +141,16 @@ func sddlFor(acc Access) (string, error) {
|
|
|
|
|
|
sddl := fmt.Sprintf("D:P(A;;GA;;;%s)(A;;GA;;;SY)(A;;GA;;;BA)", user.User.Sid.String())
|
|
|
if acc.Group != nil {
|
|
|
- sddl += fmt.Sprintf("(A;;GRGW;;;%s)", acc.Group.ID)
|
|
|
+ sddl += fmt.Sprintf("(A;;%s;;;%s)", groupPipeMask, acc.Group.ID)
|
|
|
}
|
|
|
return sddl, nil
|
|
|
}
|
|
|
|
|
|
+// groupPipeMask is the access a configured group gets on the pipe: FILE_GENERIC_READ
|
|
|
+// (0x120089) and FILE_GENERIC_WRITE (0x120116) without FILE_CREATE_PIPE_INSTANCE (0x4),
|
|
|
+// written as SDDL writes a mask it has no letters for.
|
|
|
+const groupPipeMask = "0x12019b"
|
|
|
+
|
|
|
// removeSocket is a no-op: a named pipe disappears when its last handle closes, so
|
|
|
// there is nothing to unlink and no stale instance to clean up.
|
|
|
func removeSocket(path string, id socketID) {}
|