consul: Deny delete anonymous or update of root policies
This commit is contained in:
parent
8fad8538e8
commit
ce98b0abbd
|
@ -27,7 +27,7 @@ func (a *ACL) Apply(args *structs.ACLRequest, reply *string) error {
|
|||
return fmt.Errorf(aclDisabled)
|
||||
}
|
||||
|
||||
// Verify token is permitted to list ACLs
|
||||
// Verify token is permitted to modify ACLs
|
||||
if acl, err := a.srv.resolveToken(args.Token); err != nil {
|
||||
return err
|
||||
} else if acl == nil || !acl.ACLModify() {
|
||||
|
@ -44,6 +44,11 @@ func (a *ACL) Apply(args *structs.ACLRequest, reply *string) error {
|
|||
return fmt.Errorf("Invalid ACL Type")
|
||||
}
|
||||
|
||||
// Verify this is not a root ACL
|
||||
if acl.RootACL(args.ACL.ID) != nil {
|
||||
return fmt.Errorf("%s: Cannot modify root ACL", permissionDenied)
|
||||
}
|
||||
|
||||
// Validate the rules compile
|
||||
_, err := acl.Parse(args.ACL.Rules)
|
||||
if err != nil {
|
||||
|
@ -53,6 +58,8 @@ func (a *ACL) Apply(args *structs.ACLRequest, reply *string) error {
|
|||
case structs.ACLDelete:
|
||||
if args.ACL.ID == "" {
|
||||
return fmt.Errorf("Missing ACL ID")
|
||||
} else if args.ACL.ID == anonymousToken {
|
||||
return fmt.Errorf("%s: Cannot delete anonymous token", permissionDenied)
|
||||
}
|
||||
|
||||
default:
|
||||
|
|
|
@ -174,6 +174,64 @@ func TestACLEndpoint_Apply_Denied(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestACLEndpoint_Apply_DeleteAnon(t *testing.T) {
|
||||
dir1, s1 := testServerWithConfig(t, func(c *Config) {
|
||||
c.ACLDatacenter = "dc1"
|
||||
c.ACLMasterToken = "root"
|
||||
})
|
||||
defer os.RemoveAll(dir1)
|
||||
defer s1.Shutdown()
|
||||
client := rpcClient(t, s1)
|
||||
defer client.Close()
|
||||
|
||||
testutil.WaitForLeader(t, client.Call, "dc1")
|
||||
|
||||
arg := structs.ACLRequest{
|
||||
Datacenter: "dc1",
|
||||
Op: structs.ACLDelete,
|
||||
ACL: structs.ACL{
|
||||
ID: anonymousToken,
|
||||
Name: "User token",
|
||||
Type: structs.ACLTypeClient,
|
||||
},
|
||||
WriteRequest: structs.WriteRequest{Token: "root"},
|
||||
}
|
||||
var out string
|
||||
err := client.Call("ACL.Apply", &arg, &out)
|
||||
if err == nil || !strings.Contains(err.Error(), "delete anonymous") {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestACLEndpoint_Apply_RootChange(t *testing.T) {
|
||||
dir1, s1 := testServerWithConfig(t, func(c *Config) {
|
||||
c.ACLDatacenter = "dc1"
|
||||
c.ACLMasterToken = "root"
|
||||
})
|
||||
defer os.RemoveAll(dir1)
|
||||
defer s1.Shutdown()
|
||||
client := rpcClient(t, s1)
|
||||
defer client.Close()
|
||||
|
||||
testutil.WaitForLeader(t, client.Call, "dc1")
|
||||
|
||||
arg := structs.ACLRequest{
|
||||
Datacenter: "dc1",
|
||||
Op: structs.ACLSet,
|
||||
ACL: structs.ACL{
|
||||
ID: "manage",
|
||||
Name: "User token",
|
||||
Type: structs.ACLTypeClient,
|
||||
},
|
||||
WriteRequest: structs.WriteRequest{Token: "root"},
|
||||
}
|
||||
var out string
|
||||
err := client.Call("ACL.Apply", &arg, &out)
|
||||
if err == nil || !strings.Contains(err.Error(), "root ACL") {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestACLEndpoint_Get(t *testing.T) {
|
||||
dir1, s1 := testServerWithConfig(t, func(c *Config) {
|
||||
c.ACLDatacenter = "dc1"
|
||||
|
|
Loading…
Reference in New Issue