Merge pull request #10738 from hashicorp/dnephin/remove-authorizer-nil-checks-2
acl: remove the last of the authz == nil checks
This commit is contained in:
commit
3dc113ada6
|
@ -391,7 +391,7 @@ func (s *HTTPHandlers) AgentService(resp http.ResponseWriter, req *http.Request)
|
||||||
}
|
}
|
||||||
var authzContext acl.AuthorizerContext
|
var authzContext acl.AuthorizerContext
|
||||||
svc.FillAuthzContext(&authzContext)
|
svc.FillAuthzContext(&authzContext)
|
||||||
if authz != nil && authz.ServiceRead(svc.Service, &authzContext) != acl.Allow {
|
if authz.ServiceRead(svc.Service, &authzContext) != acl.Allow {
|
||||||
return "", nil, acl.ErrPermissionDenied
|
return "", nil, acl.ErrPermissionDenied
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -837,7 +837,7 @@ func (s *HTTPHandlers) AgentHealthServiceByID(resp http.ResponseWriter, req *htt
|
||||||
dc := s.agent.config.Datacenter
|
dc := s.agent.config.Datacenter
|
||||||
|
|
||||||
if service := s.agent.State.Service(sid); service != nil {
|
if service := s.agent.State.Service(sid); service != nil {
|
||||||
if authz != nil && authz.ServiceRead(service.Service, &authzContext) != acl.Allow {
|
if authz.ServiceRead(service.Service, &authzContext) != acl.Allow {
|
||||||
return nil, acl.ErrPermissionDenied
|
return nil, acl.ErrPermissionDenied
|
||||||
}
|
}
|
||||||
code, status, healthChecks := agentHealthService(sid, s)
|
code, status, healthChecks := agentHealthService(sid, s)
|
||||||
|
@ -886,7 +886,7 @@ func (s *HTTPHandlers) AgentHealthServiceByName(resp http.ResponseWriter, req *h
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if authz != nil && authz.ServiceRead(serviceName, &authzContext) != acl.Allow {
|
if authz.ServiceRead(serviceName, &authzContext) != acl.Allow {
|
||||||
return nil, acl.ErrPermissionDenied
|
return nil, acl.ErrPermissionDenied
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,7 @@ func (a *Agent) ConnectAuthorize(token string,
|
||||||
return returnErr(err)
|
return returnErr(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if authz != nil && authz.ServiceWrite(req.Target, &authzContext) != acl.Allow {
|
if authz.ServiceWrite(req.Target, &authzContext) != acl.Allow {
|
||||||
return returnErr(acl.ErrPermissionDenied)
|
return returnErr(acl.ErrPermissionDenied)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -118,14 +118,14 @@ func servicePreApply(service *structs.NodeService, authz acl.Authorizer) error {
|
||||||
// later if version 0.8 is enabled, so we can eventually just
|
// later if version 0.8 is enabled, so we can eventually just
|
||||||
// delete this and do all the ACL checks down there.
|
// delete this and do all the ACL checks down there.
|
||||||
if service.Service != structs.ConsulServiceName {
|
if service.Service != structs.ConsulServiceName {
|
||||||
if authz != nil && authz.ServiceWrite(service.Service, &authzContext) != acl.Allow {
|
if authz.ServiceWrite(service.Service, &authzContext) != acl.Allow {
|
||||||
return acl.ErrPermissionDenied
|
return acl.ErrPermissionDenied
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Proxies must have write permission on their destination
|
// Proxies must have write permission on their destination
|
||||||
if service.Kind == structs.ServiceKindConnectProxy {
|
if service.Kind == structs.ServiceKindConnectProxy {
|
||||||
if authz != nil && authz.ServiceWrite(service.Proxy.DestinationServiceName, &authzContext) != acl.Allow {
|
if authz.ServiceWrite(service.Proxy.DestinationServiceName, &authzContext) != acl.Allow {
|
||||||
return acl.ErrPermissionDenied
|
return acl.ErrPermissionDenied
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,15 +200,12 @@ func (c *Catalog) Register(args *structs.RegisterRequest, reply *struct{}) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the complete register request against the given ACL policy.
|
// Check the complete register request against the given ACL policy.
|
||||||
if authz != nil {
|
_, ns, err := state.NodeServices(nil, args.Node, entMeta)
|
||||||
state := c.srv.fsm.State()
|
if err != nil {
|
||||||
_, ns, err := state.NodeServices(nil, args.Node, entMeta)
|
return fmt.Errorf("Node lookup failed: %v", err)
|
||||||
if err != nil {
|
}
|
||||||
return fmt.Errorf("Node lookup failed: %v", err)
|
if err := vetRegisterWithACL(authz, args, ns); err != nil {
|
||||||
}
|
return err
|
||||||
if err := vetRegisterWithACL(authz, args, ns); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = c.srv.raftApply(structs.RegisterRequestType, args)
|
_, err = c.srv.raftApply(structs.RegisterRequestType, args)
|
||||||
|
@ -238,29 +235,26 @@ func (c *Catalog) Deregister(args *structs.DeregisterRequest, reply *struct{}) e
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the complete deregister request against the given ACL policy.
|
// Check the complete deregister request against the given ACL policy.
|
||||||
if authz != nil {
|
state := c.srv.fsm.State()
|
||||||
state := c.srv.fsm.State()
|
|
||||||
|
|
||||||
var ns *structs.NodeService
|
var ns *structs.NodeService
|
||||||
if args.ServiceID != "" {
|
if args.ServiceID != "" {
|
||||||
_, ns, err = state.NodeService(args.Node, args.ServiceID, &args.EnterpriseMeta)
|
_, ns, err = state.NodeService(args.Node, args.ServiceID, &args.EnterpriseMeta)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Service lookup failed: %v", err)
|
return fmt.Errorf("Service lookup failed: %v", err)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var nc *structs.HealthCheck
|
var nc *structs.HealthCheck
|
||||||
if args.CheckID != "" {
|
if args.CheckID != "" {
|
||||||
_, nc, err = state.NodeCheck(args.Node, args.CheckID, &args.EnterpriseMeta)
|
_, nc, err = state.NodeCheck(args.Node, args.CheckID, &args.EnterpriseMeta)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Check lookup failed: %v", err)
|
return fmt.Errorf("Check lookup failed: %v", err)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := vetDeregisterWithACL(authz, args, ns, nc); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := vetDeregisterWithACL(authz, args, ns, nc); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = c.srv.raftApply(structs.DeregisterRequestType, args)
|
_, err = c.srv.raftApply(structs.DeregisterRequestType, args)
|
||||||
|
@ -456,7 +450,7 @@ func (c *Catalog) ServiceNodes(args *structs.ServiceSpecificRequest, reply *stru
|
||||||
// If we're doing a connect query, we need read access to the service
|
// If we're doing a connect query, we need read access to the service
|
||||||
// we're trying to find proxies for, so check that.
|
// we're trying to find proxies for, so check that.
|
||||||
if args.Connect {
|
if args.Connect {
|
||||||
if authz != nil && authz.ServiceRead(args.ServiceName, &authzContext) != acl.Allow {
|
if authz.ServiceRead(args.ServiceName, &authzContext) != acl.Allow {
|
||||||
// Just return nil, which will return an empty response (tested)
|
// Just return nil, which will return an empty response (tested)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -659,7 +653,7 @@ func (c *Catalog) GatewayServices(args *structs.ServiceSpecificRequest, reply *s
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if authz != nil && authz.ServiceRead(args.ServiceName, &authzContext) != acl.Allow {
|
if authz.ServiceRead(args.ServiceName, &authzContext) != acl.Allow {
|
||||||
return acl.ErrPermissionDenied
|
return acl.ErrPermissionDenied
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,7 +81,7 @@ func (c *ConfigEntry) Apply(args *structs.ConfigEntryRequest, reply *bool) error
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if authz != nil && !args.Entry.CanWrite(authz) {
|
if !args.Entry.CanWrite(authz) {
|
||||||
return acl.ErrPermissionDenied
|
return acl.ErrPermissionDenied
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ func (c *ConfigEntry) Get(args *structs.ConfigEntryQuery, reply *structs.ConfigE
|
||||||
}
|
}
|
||||||
lookupEntry.GetEnterpriseMeta().Merge(&args.EnterpriseMeta)
|
lookupEntry.GetEnterpriseMeta().Merge(&args.EnterpriseMeta)
|
||||||
|
|
||||||
if authz != nil && !lookupEntry.CanRead(authz) {
|
if !lookupEntry.CanRead(authz) {
|
||||||
return acl.ErrPermissionDenied
|
return acl.ErrPermissionDenied
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,7 +180,7 @@ func (c *ConfigEntry) List(args *structs.ConfigEntryQuery, reply *structs.Indexe
|
||||||
// Filter the entries returned by ACL permissions.
|
// Filter the entries returned by ACL permissions.
|
||||||
filteredEntries := make([]structs.ConfigEntry, 0, len(entries))
|
filteredEntries := make([]structs.ConfigEntry, 0, len(entries))
|
||||||
for _, entry := range entries {
|
for _, entry := range entries {
|
||||||
if authz != nil && !entry.CanRead(authz) {
|
if !entry.CanRead(authz) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
filteredEntries = append(filteredEntries, entry)
|
filteredEntries = append(filteredEntries, entry)
|
||||||
|
@ -240,7 +240,7 @@ func (c *ConfigEntry) ListAll(args *structs.ConfigEntryListAllRequest, reply *st
|
||||||
// Filter the entries returned by ACL permissions or by the provided kinds.
|
// Filter the entries returned by ACL permissions or by the provided kinds.
|
||||||
filteredEntries := make([]structs.ConfigEntry, 0, len(entries))
|
filteredEntries := make([]structs.ConfigEntry, 0, len(entries))
|
||||||
for _, entry := range entries {
|
for _, entry := range entries {
|
||||||
if authz != nil && !entry.CanRead(authz) {
|
if !entry.CanRead(authz) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// Doing this filter outside of memdb isn't terribly
|
// Doing this filter outside of memdb isn't terribly
|
||||||
|
@ -290,7 +290,7 @@ func (c *ConfigEntry) Delete(args *structs.ConfigEntryRequest, reply *struct{})
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if authz != nil && !args.Entry.CanWrite(authz) {
|
if !args.Entry.CanWrite(authz) {
|
||||||
return acl.ErrPermissionDenied
|
return acl.ErrPermissionDenied
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,7 +315,7 @@ func (c *ConfigEntry) ResolveServiceConfig(args *structs.ServiceConfigRequest, r
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if authz != nil && authz.ServiceRead(args.Name, &authzContext) != acl.Allow {
|
if authz.ServiceRead(args.Name, &authzContext) != acl.Allow {
|
||||||
return acl.ErrPermissionDenied
|
return acl.ErrPermissionDenied
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -142,12 +142,10 @@ func (c *Coordinate) Update(args *structs.CoordinateUpdateRequest, reply *struct
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if authz != nil {
|
var authzContext acl.AuthorizerContext
|
||||||
var authzContext acl.AuthorizerContext
|
structs.DefaultEnterpriseMetaInDefaultPartition().FillAuthzContext(&authzContext)
|
||||||
structs.DefaultEnterpriseMetaInDefaultPartition().FillAuthzContext(&authzContext)
|
if authz.NodeWrite(args.Node, &authzContext) != acl.Allow {
|
||||||
if authz.NodeWrite(args.Node, &authzContext) != acl.Allow {
|
return acl.ErrPermissionDenied
|
||||||
return acl.ErrPermissionDenied
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the coordinate to the map of pending updates.
|
// Add the coordinate to the map of pending updates.
|
||||||
|
@ -226,12 +224,10 @@ func (c *Coordinate) Node(args *structs.NodeSpecificRequest, reply *structs.Inde
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if authz != nil {
|
var authzContext acl.AuthorizerContext
|
||||||
var authzContext acl.AuthorizerContext
|
structs.WildcardEnterpriseMetaInDefaultPartition().FillAuthzContext(&authzContext)
|
||||||
structs.WildcardEnterpriseMetaInDefaultPartition().FillAuthzContext(&authzContext)
|
if authz.NodeRead(args.Node, &authzContext) != acl.Allow {
|
||||||
if authz.NodeRead(args.Node, &authzContext) != acl.Allow {
|
return acl.ErrPermissionDenied
|
||||||
return acl.ErrPermissionDenied
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.srv.blockingQuery(&args.QueryOptions,
|
return c.srv.blockingQuery(&args.QueryOptions,
|
||||||
|
|
|
@ -207,7 +207,7 @@ func (h *Health) ServiceNodes(args *structs.ServiceSpecificRequest, reply *struc
|
||||||
// If we're doing a connect or ingress query, we need read access to the service
|
// If we're doing a connect or ingress query, we need read access to the service
|
||||||
// we're trying to find proxies for, so check that.
|
// we're trying to find proxies for, so check that.
|
||||||
if args.Connect || args.Ingress {
|
if args.Connect || args.Ingress {
|
||||||
if authz != nil && authz.ServiceRead(args.ServiceName, &authzContext) != acl.Allow {
|
if authz.ServiceRead(args.ServiceName, &authzContext) != acl.Allow {
|
||||||
// Just return nil, which will return an empty response (tested)
|
// Just return nil, which will return an empty response (tested)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -593,24 +593,22 @@ func (s *Intention) Match(args *structs.IntentionQueryRequest, reply *structs.In
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if authz != nil {
|
var authzContext acl.AuthorizerContext
|
||||||
var authzContext acl.AuthorizerContext
|
// Go through each entry to ensure we have intention:read for the resource.
|
||||||
// Go through each entry to ensure we have intention:read for the resource.
|
|
||||||
|
|
||||||
// TODO - should we do this instead of filtering the result set? This will only allow
|
// TODO - should we do this instead of filtering the result set? This will only allow
|
||||||
// queries for which the token has intention:read permissions on the requested side
|
// queries for which the token has intention:read permissions on the requested side
|
||||||
// of the service. Should it instead return all matches that it would be able to list.
|
// of the service. Should it instead return all matches that it would be able to list.
|
||||||
// if so we should remove this and call filterACL instead. Based on how this is used
|
// if so we should remove this and call filterACL instead. Based on how this is used
|
||||||
// its probably fine. If you have intention read on the source just do a source type
|
// its probably fine. If you have intention read on the source just do a source type
|
||||||
// matching, if you have it on the dest then perform a dest type match.
|
// matching, if you have it on the dest then perform a dest type match.
|
||||||
for _, entry := range args.Match.Entries {
|
for _, entry := range args.Match.Entries {
|
||||||
entry.FillAuthzContext(&authzContext)
|
entry.FillAuthzContext(&authzContext)
|
||||||
if prefix := entry.Name; prefix != "" && authz.IntentionRead(prefix, &authzContext) != acl.Allow {
|
if prefix := entry.Name; prefix != "" && authz.IntentionRead(prefix, &authzContext) != acl.Allow {
|
||||||
accessorID := s.aclAccessorID(args.Token)
|
accessorID := s.aclAccessorID(args.Token)
|
||||||
// todo(kit) Migrate intention access denial logging over to audit logging when we implement it
|
// todo(kit) Migrate intention access denial logging over to audit logging when we implement it
|
||||||
s.logger.Warn("Operation on intention prefix denied due to ACLs", "prefix", prefix, "accessorID", accessorID)
|
s.logger.Warn("Operation on intention prefix denied due to ACLs", "prefix", prefix, "accessorID", accessorID)
|
||||||
return acl.ErrPermissionDenied
|
return acl.ErrPermissionDenied
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -690,7 +688,7 @@ func (s *Intention) Check(args *structs.IntentionQueryRequest, reply *structs.In
|
||||||
if prefix, ok := query.GetACLPrefix(); ok {
|
if prefix, ok := query.GetACLPrefix(); ok {
|
||||||
var authzContext acl.AuthorizerContext
|
var authzContext acl.AuthorizerContext
|
||||||
query.FillAuthzContext(&authzContext)
|
query.FillAuthzContext(&authzContext)
|
||||||
if authz != nil && authz.ServiceRead(prefix, &authzContext) != acl.Allow {
|
if authz.ServiceRead(prefix, &authzContext) != acl.Allow {
|
||||||
accessorID := s.aclAccessorID(args.Token)
|
accessorID := s.aclAccessorID(args.Token)
|
||||||
// todo(kit) Migrate intention access denial logging over to audit logging when we implement it
|
// todo(kit) Migrate intention access denial logging over to audit logging when we implement it
|
||||||
s.logger.Warn("test on intention denied due to ACLs", "prefix", prefix, "accessorID", accessorID)
|
s.logger.Warn("test on intention denied due to ACLs", "prefix", prefix, "accessorID", accessorID)
|
||||||
|
@ -710,10 +708,7 @@ func (s *Intention) Check(args *structs.IntentionQueryRequest, reply *structs.In
|
||||||
// NOTE(mitchellh): This is the same behavior as the agent authorize
|
// NOTE(mitchellh): This is the same behavior as the agent authorize
|
||||||
// endpoint. If this behavior is incorrect, we should also change it there
|
// endpoint. If this behavior is incorrect, we should also change it there
|
||||||
// which is much more important.
|
// which is much more important.
|
||||||
defaultDecision := acl.Allow
|
defaultDecision := authz.IntentionDefaultAllow(nil)
|
||||||
if authz != nil {
|
|
||||||
defaultDecision = authz.IntentionDefaultAllow(nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
state := s.srv.fsm.State()
|
state := s.srv.fsm.State()
|
||||||
|
|
||||||
|
|
|
@ -161,7 +161,7 @@ func (m *Internal) ServiceTopology(args *structs.ServiceSpecificRequest, reply *
|
||||||
if err := m.srv.validateEnterpriseRequest(&args.EnterpriseMeta, false); err != nil {
|
if err := m.srv.validateEnterpriseRequest(&args.EnterpriseMeta, false); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if authz != nil && authz.ServiceRead(args.ServiceName, &authzContext) != acl.Allow {
|
if authz.ServiceRead(args.ServiceName, &authzContext) != acl.Allow {
|
||||||
return acl.ErrPermissionDenied
|
return acl.ErrPermissionDenied
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,10 +169,7 @@ func (m *Internal) ServiceTopology(args *structs.ServiceSpecificRequest, reply *
|
||||||
&args.QueryOptions,
|
&args.QueryOptions,
|
||||||
&reply.QueryMeta,
|
&reply.QueryMeta,
|
||||||
func(ws memdb.WatchSet, state *state.Store) error {
|
func(ws memdb.WatchSet, state *state.Store) error {
|
||||||
defaultAllow := acl.Allow
|
defaultAllow := authz.IntentionDefaultAllow(nil)
|
||||||
if authz != nil {
|
|
||||||
defaultAllow = authz.IntentionDefaultAllow(nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
index, topology, err := state.ServiceTopology(ws, args.Datacenter, args.ServiceName, args.ServiceKind, defaultAllow, &args.EnterpriseMeta)
|
index, topology, err := state.ServiceTopology(ws, args.Datacenter, args.ServiceName, args.ServiceKind, defaultAllow, &args.EnterpriseMeta)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -216,10 +213,7 @@ func (m *Internal) IntentionUpstreams(args *structs.ServiceSpecificRequest, repl
|
||||||
&args.QueryOptions,
|
&args.QueryOptions,
|
||||||
&reply.QueryMeta,
|
&reply.QueryMeta,
|
||||||
func(ws memdb.WatchSet, state *state.Store) error {
|
func(ws memdb.WatchSet, state *state.Store) error {
|
||||||
defaultDecision := acl.Allow
|
defaultDecision := authz.IntentionDefaultAllow(nil)
|
||||||
if authz != nil {
|
|
||||||
defaultDecision = authz.IntentionDefaultAllow(nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
sn := structs.NewServiceName(args.ServiceName, &args.EnterpriseMeta)
|
sn := structs.NewServiceName(args.ServiceName, &args.EnterpriseMeta)
|
||||||
index, services, err := state.IntentionTopology(ws, sn, false, defaultDecision)
|
index, services, err := state.IntentionTopology(ws, sn, false, defaultDecision)
|
||||||
|
@ -254,7 +248,7 @@ func (m *Internal) GatewayServiceDump(args *structs.ServiceSpecificRequest, repl
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need read access to the gateway we're trying to find services for, so check that first.
|
// We need read access to the gateway we're trying to find services for, so check that first.
|
||||||
if authz != nil && authz.ServiceRead(args.ServiceName, &authzContext) != acl.Allow {
|
if authz.ServiceRead(args.ServiceName, &authzContext) != acl.Allow {
|
||||||
return acl.ErrPermissionDenied
|
return acl.ErrPermissionDenied
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,7 +332,7 @@ func (m *Internal) GatewayIntentions(args *structs.IntentionQueryRequest, reply
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need read access to the gateway we're trying to find intentions for, so check that first.
|
// We need read access to the gateway we're trying to find intentions for, so check that first.
|
||||||
if authz != nil && authz.ServiceRead(args.Match.Entries[0].Name, &authzContext) != acl.Allow {
|
if authz.ServiceRead(args.Match.Entries[0].Name, &authzContext) != acl.Allow {
|
||||||
return acl.ErrPermissionDenied
|
return acl.ErrPermissionDenied
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,37 +39,35 @@ func kvsPreApply(logger hclog.Logger, srv *Server, authz acl.Authorizer, op api.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply the ACL policy if any.
|
// Apply the ACL policy if any.
|
||||||
if authz != nil {
|
switch op {
|
||||||
switch op {
|
case api.KVDeleteTree:
|
||||||
case api.KVDeleteTree:
|
var authzContext acl.AuthorizerContext
|
||||||
var authzContext acl.AuthorizerContext
|
dirEnt.FillAuthzContext(&authzContext)
|
||||||
dirEnt.FillAuthzContext(&authzContext)
|
|
||||||
|
|
||||||
if authz.KeyWritePrefix(dirEnt.Key, &authzContext) != acl.Allow {
|
if authz.KeyWritePrefix(dirEnt.Key, &authzContext) != acl.Allow {
|
||||||
return false, acl.ErrPermissionDenied
|
return false, acl.ErrPermissionDenied
|
||||||
}
|
}
|
||||||
|
|
||||||
case api.KVGet, api.KVGetTree:
|
case api.KVGet, api.KVGetTree:
|
||||||
// Filtering for GETs is done on the output side.
|
// Filtering for GETs is done on the output side.
|
||||||
|
|
||||||
case api.KVCheckSession, api.KVCheckIndex:
|
case api.KVCheckSession, api.KVCheckIndex:
|
||||||
// These could reveal information based on the outcome
|
// These could reveal information based on the outcome
|
||||||
// of the transaction, and they operate on individual
|
// of the transaction, and they operate on individual
|
||||||
// keys so we check them here.
|
// keys so we check them here.
|
||||||
var authzContext acl.AuthorizerContext
|
var authzContext acl.AuthorizerContext
|
||||||
dirEnt.FillAuthzContext(&authzContext)
|
dirEnt.FillAuthzContext(&authzContext)
|
||||||
|
|
||||||
if authz.KeyRead(dirEnt.Key, &authzContext) != acl.Allow {
|
if authz.KeyRead(dirEnt.Key, &authzContext) != acl.Allow {
|
||||||
return false, acl.ErrPermissionDenied
|
return false, acl.ErrPermissionDenied
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
var authzContext acl.AuthorizerContext
|
var authzContext acl.AuthorizerContext
|
||||||
dirEnt.FillAuthzContext(&authzContext)
|
dirEnt.FillAuthzContext(&authzContext)
|
||||||
|
|
||||||
if authz.KeyWrite(dirEnt.Key, &authzContext) != acl.Allow {
|
if authz.KeyWrite(dirEnt.Key, &authzContext) != acl.Allow {
|
||||||
return false, acl.ErrPermissionDenied
|
return false, acl.ErrPermissionDenied
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,7 +242,7 @@ func (k *KVS) ListKeys(args *structs.KeyListRequest, reply *structs.IndexedKeyLi
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if authz != nil && k.srv.config.ACLEnableKeyListPolicy && authz.KeyList(args.Prefix, &authzContext) != acl.Allow {
|
if k.srv.config.ACLEnableKeyListPolicy && authz.KeyList(args.Prefix, &authzContext) != acl.Allow {
|
||||||
return acl.ErrPermissionDenied
|
return acl.ErrPermissionDenied
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,9 +263,7 @@ func (k *KVS) ListKeys(args *structs.KeyListRequest, reply *structs.IndexedKeyLi
|
||||||
reply.Index = index
|
reply.Index = index
|
||||||
}
|
}
|
||||||
|
|
||||||
if authz != nil {
|
entries = FilterDirEnt(authz, entries)
|
||||||
entries = FilterDirEnt(authz, entries)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Collect the keys from the filtered entries
|
// Collect the keys from the filtered entries
|
||||||
prefixLen := len(args.Prefix)
|
prefixLen := len(args.Prefix)
|
||||||
|
|
|
@ -72,29 +72,27 @@ func (s *Session) Apply(args *structs.SessionRequest, reply *string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if authz != nil {
|
switch args.Op {
|
||||||
switch args.Op {
|
case structs.SessionDestroy:
|
||||||
case structs.SessionDestroy:
|
state := s.srv.fsm.State()
|
||||||
state := s.srv.fsm.State()
|
_, existing, err := state.SessionGet(nil, args.Session.ID, &args.Session.EnterpriseMeta)
|
||||||
_, existing, err := state.SessionGet(nil, args.Session.ID, &args.Session.EnterpriseMeta)
|
if err != nil {
|
||||||
if err != nil {
|
return fmt.Errorf("Session lookup failed: %v", err)
|
||||||
return fmt.Errorf("Session lookup failed: %v", err)
|
|
||||||
}
|
|
||||||
if existing == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if authz.SessionWrite(existing.Node, &authzContext) != acl.Allow {
|
|
||||||
return acl.ErrPermissionDenied
|
|
||||||
}
|
|
||||||
|
|
||||||
case structs.SessionCreate:
|
|
||||||
if authz.SessionWrite(args.Session.Node, &authzContext) != acl.Allow {
|
|
||||||
return acl.ErrPermissionDenied
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("Invalid session operation %q", args.Op)
|
|
||||||
}
|
}
|
||||||
|
if existing == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if authz.SessionWrite(existing.Node, &authzContext) != acl.Allow {
|
||||||
|
return acl.ErrPermissionDenied
|
||||||
|
}
|
||||||
|
|
||||||
|
case structs.SessionCreate:
|
||||||
|
if authz.SessionWrite(args.Session.Node, &authzContext) != acl.Allow {
|
||||||
|
return acl.ErrPermissionDenied
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("Invalid session operation %q", args.Op)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that the specified behavior is allowed
|
// Ensure that the specified behavior is allowed
|
||||||
|
@ -310,7 +308,7 @@ func (s *Session) Renew(args *structs.SessionSpecificRequest,
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if authz != nil && authz.SessionWrite(session.Node, &authzContext) != acl.Allow {
|
if authz.SessionWrite(session.Node, &authzContext) != acl.Allow {
|
||||||
return acl.ErrPermissionDenied
|
return acl.ErrPermissionDenied
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,9 +81,9 @@ func (t *Txn) preCheck(authorizer acl.Authorizer, ops structs.TxnOps) structs.Tx
|
||||||
}
|
}
|
||||||
|
|
||||||
service := &op.Service.Service
|
service := &op.Service.Service
|
||||||
// This is intentionally nil as we will authorize the request
|
// acl.ManageAll is used here because the request will be authorized
|
||||||
// using vetServiceTxnOp next instead of doing it in servicePreApply
|
// later using vetServiceTxnOp.
|
||||||
if err := servicePreApply(service, nil); err != nil {
|
if err := servicePreApply(service, acl.ManageAll()); err != nil {
|
||||||
errors = append(errors, &structs.TxnError{
|
errors = append(errors, &structs.TxnError{
|
||||||
OpIndex: i,
|
OpIndex: i,
|
||||||
What: err.Error(),
|
What: err.Error(),
|
||||||
|
|
|
@ -128,16 +128,14 @@ RUN_QUERY:
|
||||||
events := s.agent.UserEvents()
|
events := s.agent.UserEvents()
|
||||||
|
|
||||||
// Filter the events using the ACL, if present
|
// Filter the events using the ACL, if present
|
||||||
if authz != nil {
|
for i := 0; i < len(events); i++ {
|
||||||
for i := 0; i < len(events); i++ {
|
name := events[i].Name
|
||||||
name := events[i].Name
|
if authz.EventRead(name, nil) == acl.Allow {
|
||||||
if authz.EventRead(name, nil) == acl.Allow {
|
continue
|
||||||
continue
|
|
||||||
}
|
|
||||||
s.agent.logger.Debug("dropping event from result due to ACLs", "event", name)
|
|
||||||
events = append(events[:i], events[i+1:]...)
|
|
||||||
i--
|
|
||||||
}
|
}
|
||||||
|
s.agent.logger.Debug("dropping event from result due to ACLs", "event", name)
|
||||||
|
events = append(events[:i], events[i+1:]...)
|
||||||
|
i--
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter the events if requested
|
// Filter the events if requested
|
||||||
|
|
|
@ -9,12 +9,13 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/hashicorp/go-hclog"
|
||||||
|
|
||||||
"github.com/hashicorp/consul/acl"
|
"github.com/hashicorp/consul/acl"
|
||||||
"github.com/hashicorp/consul/agent/config"
|
"github.com/hashicorp/consul/agent/config"
|
||||||
"github.com/hashicorp/consul/agent/structs"
|
"github.com/hashicorp/consul/agent/structs"
|
||||||
"github.com/hashicorp/consul/api"
|
"github.com/hashicorp/consul/api"
|
||||||
"github.com/hashicorp/consul/logging"
|
"github.com/hashicorp/consul/logging"
|
||||||
"github.com/hashicorp/go-hclog"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ServiceSummary is used to summarize a service
|
// ServiceSummary is used to summarize a service
|
||||||
|
@ -607,17 +608,15 @@ func (s *HTTPHandlers) UIMetricsProxy(resp http.ResponseWriter, req *http.Reques
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if authz != nil {
|
// This endpoint requires wildcard read on all services and all nodes.
|
||||||
// This endpoint requires wildcard read on all services and all nodes.
|
//
|
||||||
//
|
// In enterprise it requires this _in all namespaces_ too.
|
||||||
// In enterprise it requires this _in all namespaces_ too.
|
wildMeta := structs.WildcardEnterpriseMetaInDefaultPartition()
|
||||||
wildMeta := structs.WildcardEnterpriseMetaInDefaultPartition()
|
var authzContext acl.AuthorizerContext
|
||||||
var authzContext acl.AuthorizerContext
|
wildMeta.FillAuthzContext(&authzContext)
|
||||||
wildMeta.FillAuthzContext(&authzContext)
|
|
||||||
|
|
||||||
if authz.NodeReadAll(&authzContext) != acl.Allow || authz.ServiceReadAll(&authzContext) != acl.Allow {
|
if authz.NodeReadAll(&authzContext) != acl.Allow || authz.ServiceReadAll(&authzContext) != acl.Allow {
|
||||||
return nil, acl.ErrPermissionDenied
|
return nil, acl.ErrPermissionDenied
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log := s.agent.logger.Named(logging.UIMetricsProxy)
|
log := s.agent.logger.Named(logging.UIMetricsProxy)
|
||||||
|
|
Loading…
Reference in New Issue