ForceLeave endpoint must use Server.ResolveToken

The ForceLeaveRequest endpoint may only be called on servers, but the
code was using a Client to resolve tokens. This would cause a panic when
an agent wasn't both a Server and a Client.
This commit is contained in:
Michael Schurter
2017-10-09 15:49:04 -07:00
parent 402f2bcec7
commit c39a2333d9
8 changed files with 45 additions and 45 deletions

View File

@@ -142,7 +142,7 @@ func (s *HTTPServer) AgentForceLeaveRequest(resp http.ResponseWriter, req *http.
s.parseToken(req, &secret)
// Check agent write permissions
if aclObj, err := s.agent.Client().ResolveToken(secret); err != nil {
if aclObj, err := s.agent.Server().ResolveToken(secret); err != nil {
return nil, err
} else if aclObj != nil && !aclObj.AllowAgentWrite() {
return nil, structs.ErrPermissionDenied

View File

@@ -10,9 +10,9 @@ import (
"github.com/hashicorp/nomad/nomad/structs"
)
// resolveToken is used to translate an ACL Token Secret ID into
// ResolveToken is used to translate an ACL Token Secret ID into
// an ACL object, nil if ACLs are disabled, or an error.
func (s *Server) resolveToken(secretID string) (*acl.ACL, error) {
func (s *Server) ResolveToken(secretID string) (*acl.ACL, error) {
// Fast-path if ACLs are disabled
if !s.config.ACLEnabled {
return nil, nil

View File

@@ -44,7 +44,7 @@ func (a *ACL) UpsertPolicies(args *structs.ACLPolicyUpsertRequest, reply *struct
defer metrics.MeasureSince([]string{"nomad", "acl", "upsert_policies"}, time.Now())
// Check management level permissions
if acl, err := a.srv.resolveToken(args.SecretID); err != nil {
if acl, err := a.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if acl == nil || !acl.IsManagement() {
return structs.ErrPermissionDenied
@@ -88,7 +88,7 @@ func (a *ACL) DeletePolicies(args *structs.ACLPolicyDeleteRequest, reply *struct
defer metrics.MeasureSince([]string{"nomad", "acl", "delete_policies"}, time.Now())
// Check management level permissions
if acl, err := a.srv.resolveToken(args.SecretID); err != nil {
if acl, err := a.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if acl == nil || !acl.IsManagement() {
return structs.ErrPermissionDenied
@@ -121,7 +121,7 @@ func (a *ACL) ListPolicies(args *structs.ACLPolicyListRequest, reply *structs.AC
defer metrics.MeasureSince([]string{"nomad", "acl", "list_policies"}, time.Now())
// Check management level permissions
if acl, err := a.srv.resolveToken(args.SecretID); err != nil {
if acl, err := a.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if acl == nil || !acl.IsManagement() {
return structs.ErrPermissionDenied
@@ -183,7 +183,7 @@ func (a *ACL) GetPolicy(args *structs.ACLPolicySpecificRequest, reply *structs.S
defer metrics.MeasureSince([]string{"nomad", "acl", "get_policy"}, time.Now())
// Check management level permissions
if acl, err := a.srv.resolveToken(args.SecretID); err != nil {
if acl, err := a.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if acl == nil || !acl.IsManagement() {
return structs.ErrPermissionDenied
@@ -420,7 +420,7 @@ func (a *ACL) UpsertTokens(args *structs.ACLTokenUpsertRequest, reply *structs.A
defer metrics.MeasureSince([]string{"nomad", "acl", "upsert_tokens"}, time.Now())
// Check management level permissions
if acl, err := a.srv.resolveToken(args.SecretID); err != nil {
if acl, err := a.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if acl == nil || !acl.IsManagement() {
return structs.ErrPermissionDenied
@@ -507,7 +507,7 @@ func (a *ACL) DeleteTokens(args *structs.ACLTokenDeleteRequest, reply *structs.G
defer metrics.MeasureSince([]string{"nomad", "acl", "delete_tokens"}, time.Now())
// Check management level permissions
if acl, err := a.srv.resolveToken(args.SecretID); err != nil {
if acl, err := a.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if acl == nil || !acl.IsManagement() {
return structs.ErrPermissionDenied
@@ -574,7 +574,7 @@ func (a *ACL) ListTokens(args *structs.ACLTokenListRequest, reply *structs.ACLTo
defer metrics.MeasureSince([]string{"nomad", "acl", "list_tokens"}, time.Now())
// Check management level permissions
if acl, err := a.srv.resolveToken(args.SecretID); err != nil {
if acl, err := a.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if acl == nil || !acl.IsManagement() {
return structs.ErrPermissionDenied
@@ -631,7 +631,7 @@ func (a *ACL) GetToken(args *structs.ACLTokenSpecificRequest, reply *structs.Sin
}
defer metrics.MeasureSince([]string{"nomad", "acl", "get_token"}, time.Now())
acl, err := a.srv.resolveToken(args.SecretID)
acl, err := a.srv.ResolveToken(args.SecretID)
if err != nil {
return err
}
@@ -693,7 +693,7 @@ func (a *ACL) GetTokens(args *structs.ACLTokenSetRequest, reply *structs.ACLToke
defer metrics.MeasureSince([]string{"nomad", "acl", "get_tokens"}, time.Now())
// Check management level permissions
if acl, err := a.srv.resolveToken(args.SecretID); err != nil {
if acl, err := a.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if acl == nil || !acl.IsManagement() {
return structs.ErrPermissionDenied

View File

@@ -23,7 +23,7 @@ func (a *Alloc) List(args *structs.AllocListRequest, reply *structs.AllocListRes
defer metrics.MeasureSince([]string{"nomad", "alloc", "list"}, time.Now())
// Check namespace read-job permissions
if aclObj, err := a.srv.resolveToken(args.SecretID); err != nil {
if aclObj, err := a.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if aclObj != nil && !aclObj.AllowNsOp(args.RequestNamespace(), acl.NamespaceCapabilityReadJob) {
return structs.ErrPermissionDenied
@@ -80,7 +80,7 @@ func (a *Alloc) GetAlloc(args *structs.AllocSpecificRequest,
defer metrics.MeasureSince([]string{"nomad", "alloc", "get_alloc"}, time.Now())
// Check namespace read-job permissions
if aclObj, err := a.srv.resolveToken(args.SecretID); err != nil {
if aclObj, err := a.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if aclObj != nil && !aclObj.AllowNsOp(args.RequestNamespace(), acl.NamespaceCapabilityReadJob) {
return structs.ErrPermissionDenied

View File

@@ -25,7 +25,7 @@ func (d *Deployment) GetDeployment(args *structs.DeploymentSpecificRequest,
defer metrics.MeasureSince([]string{"nomad", "deployment", "get_deployment"}, time.Now())
// Check namespace read-job permissions
if aclObj, err := d.srv.resolveToken(args.SecretID); err != nil {
if aclObj, err := d.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if aclObj != nil && !aclObj.AllowNsOp(args.RequestNamespace(), acl.NamespaceCapabilityReadJob) {
return structs.ErrPermissionDenied
@@ -75,7 +75,7 @@ func (d *Deployment) Fail(args *structs.DeploymentFailRequest, reply *structs.De
defer metrics.MeasureSince([]string{"nomad", "deployment", "fail"}, time.Now())
// Check namespace submit-job permissions
if aclObj, err := d.srv.resolveToken(args.SecretID); err != nil {
if aclObj, err := d.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if aclObj != nil && !aclObj.AllowNsOp(args.RequestNamespace(), acl.NamespaceCapabilitySubmitJob) {
return structs.ErrPermissionDenied
@@ -117,7 +117,7 @@ func (d *Deployment) Pause(args *structs.DeploymentPauseRequest, reply *structs.
defer metrics.MeasureSince([]string{"nomad", "deployment", "pause"}, time.Now())
// Check namespace submit-job permissions
if aclObj, err := d.srv.resolveToken(args.SecretID); err != nil {
if aclObj, err := d.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if aclObj != nil && !aclObj.AllowNsOp(args.RequestNamespace(), acl.NamespaceCapabilitySubmitJob) {
return structs.ErrPermissionDenied
@@ -163,7 +163,7 @@ func (d *Deployment) Promote(args *structs.DeploymentPromoteRequest, reply *stru
defer metrics.MeasureSince([]string{"nomad", "deployment", "promote"}, time.Now())
// Check namespace submit-job permissions
if aclObj, err := d.srv.resolveToken(args.SecretID); err != nil {
if aclObj, err := d.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if aclObj != nil && !aclObj.AllowNsOp(args.RequestNamespace(), acl.NamespaceCapabilitySubmitJob) {
return structs.ErrPermissionDenied
@@ -206,7 +206,7 @@ func (d *Deployment) SetAllocHealth(args *structs.DeploymentAllocHealthRequest,
defer metrics.MeasureSince([]string{"nomad", "deployment", "set_alloc_health"}, time.Now())
// Check namespace submit-job permissions
if aclObj, err := d.srv.resolveToken(args.SecretID); err != nil {
if aclObj, err := d.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if aclObj != nil && !aclObj.AllowNsOp(args.RequestNamespace(), acl.NamespaceCapabilitySubmitJob) {
return structs.ErrPermissionDenied
@@ -252,7 +252,7 @@ func (d *Deployment) List(args *structs.DeploymentListRequest, reply *structs.De
defer metrics.MeasureSince([]string{"nomad", "deployment", "list"}, time.Now())
// Check namespace read-job permissions
if aclObj, err := d.srv.resolveToken(args.SecretID); err != nil {
if aclObj, err := d.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if aclObj != nil && !aclObj.AllowNsOp(args.RequestNamespace(), acl.NamespaceCapabilityReadJob) {
return structs.ErrPermissionDenied
@@ -308,7 +308,7 @@ func (d *Deployment) Allocations(args *structs.DeploymentSpecificRequest, reply
defer metrics.MeasureSince([]string{"nomad", "deployment", "allocations"}, time.Now())
// Check namespace read-job permissions
if aclObj, err := d.srv.resolveToken(args.SecretID); err != nil {
if aclObj, err := d.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if aclObj != nil && !aclObj.AllowNsOp(args.RequestNamespace(), acl.NamespaceCapabilityReadJob) {
return structs.ErrPermissionDenied

View File

@@ -32,7 +32,7 @@ func (e *Eval) GetEval(args *structs.EvalSpecificRequest,
defer metrics.MeasureSince([]string{"nomad", "eval", "get_eval"}, time.Now())
// Check for read-job permissions
if aclObj, err := e.srv.resolveToken(args.SecretID); err != nil {
if aclObj, err := e.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if aclObj != nil && !aclObj.AllowNsOp(args.RequestNamespace(), acl.NamespaceCapabilityReadJob) {
return structs.ErrPermissionDenied
@@ -326,7 +326,7 @@ func (e *Eval) List(args *structs.EvalListRequest,
defer metrics.MeasureSince([]string{"nomad", "eval", "list"}, time.Now())
// Check for read-job permissions
if aclObj, err := e.srv.resolveToken(args.SecretID); err != nil {
if aclObj, err := e.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if aclObj != nil && !aclObj.AllowNsOp(args.RequestNamespace(), acl.NamespaceCapabilityReadJob) {
return structs.ErrPermissionDenied
@@ -383,7 +383,7 @@ func (e *Eval) Allocations(args *structs.EvalSpecificRequest,
defer metrics.MeasureSince([]string{"nomad", "eval", "allocations"}, time.Now())
// Check for read-job permissions
if aclObj, err := e.srv.resolveToken(args.SecretID); err != nil {
if aclObj, err := e.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if aclObj != nil && !aclObj.AllowNsOp(args.RequestNamespace(), acl.NamespaceCapabilityReadJob) {
return structs.ErrPermissionDenied

View File

@@ -74,7 +74,7 @@ func (j *Job) Register(args *structs.JobRegisterRequest, reply *structs.JobRegis
reply.Warnings = structs.MergeMultierrorWarnings(warnings, canonicalizeWarnings)
// Check job submission permissions
if aclObj, err := j.srv.resolveToken(args.SecretID); err != nil {
if aclObj, err := j.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if aclObj != nil {
if !aclObj.AllowNsOp(structs.DefaultNamespace, acl.NamespaceCapabilitySubmitJob) {
@@ -313,7 +313,7 @@ func (j *Job) Summary(args *structs.JobSummaryRequest,
defer metrics.MeasureSince([]string{"nomad", "job_summary", "get_job_summary"}, time.Now())
// Check for read-job permissions
if aclObj, err := j.srv.resolveToken(args.SecretID); err != nil {
if aclObj, err := j.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if aclObj != nil && !aclObj.AllowNsOp(args.RequestNamespace(), acl.NamespaceCapabilityReadJob) {
return structs.ErrPermissionDenied
@@ -355,7 +355,7 @@ func (j *Job) Validate(args *structs.JobValidateRequest, reply *structs.JobValid
defer metrics.MeasureSince([]string{"nomad", "job", "validate"}, time.Now())
// Check for read-job permissions
if aclObj, err := j.srv.resolveToken(args.SecretID); err != nil {
if aclObj, err := j.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if aclObj != nil && !aclObj.AllowNsOp(args.RequestNamespace(), acl.NamespaceCapabilityReadJob) {
return structs.ErrPermissionDenied
@@ -395,7 +395,7 @@ func (j *Job) Revert(args *structs.JobRevertRequest, reply *structs.JobRegisterR
defer metrics.MeasureSince([]string{"nomad", "job", "revert"}, time.Now())
// Check for submit-job permissions
if aclObj, err := j.srv.resolveToken(args.SecretID); err != nil {
if aclObj, err := j.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if aclObj != nil && !aclObj.AllowNsOp(args.RequestNamespace(), acl.NamespaceCapabilitySubmitJob) {
return structs.ErrPermissionDenied
@@ -460,7 +460,7 @@ func (j *Job) Stable(args *structs.JobStabilityRequest, reply *structs.JobStabil
defer metrics.MeasureSince([]string{"nomad", "job", "stable"}, time.Now())
// Check for read-job permissions
if aclObj, err := j.srv.resolveToken(args.SecretID); err != nil {
if aclObj, err := j.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if aclObj != nil && !aclObj.AllowNsOp(args.RequestNamespace(), acl.NamespaceCapabilitySubmitJob) {
return structs.ErrPermissionDenied
@@ -506,7 +506,7 @@ func (j *Job) Evaluate(args *structs.JobEvaluateRequest, reply *structs.JobRegis
defer metrics.MeasureSince([]string{"nomad", "job", "evaluate"}, time.Now())
// Check for read-job permissions
if aclObj, err := j.srv.resolveToken(args.SecretID); err != nil {
if aclObj, err := j.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if aclObj != nil && !aclObj.AllowNsOp(args.RequestNamespace(), acl.NamespaceCapabilityReadJob) {
return structs.ErrPermissionDenied
@@ -576,7 +576,7 @@ func (j *Job) Deregister(args *structs.JobDeregisterRequest, reply *structs.JobD
defer metrics.MeasureSince([]string{"nomad", "job", "deregister"}, time.Now())
// Check for submit-job permissions
if aclObj, err := j.srv.resolveToken(args.SecretID); err != nil {
if aclObj, err := j.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if aclObj != nil && !aclObj.AllowNsOp(args.RequestNamespace(), acl.NamespaceCapabilitySubmitJob) {
return structs.ErrPermissionDenied
@@ -655,7 +655,7 @@ func (j *Job) GetJob(args *structs.JobSpecificRequest,
defer metrics.MeasureSince([]string{"nomad", "job", "get_job"}, time.Now())
// Check for read-job permissions
if aclObj, err := j.srv.resolveToken(args.SecretID); err != nil {
if aclObj, err := j.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if aclObj != nil && !aclObj.AllowNsOp(args.RequestNamespace(), acl.NamespaceCapabilityReadJob) {
return structs.ErrPermissionDenied
@@ -701,7 +701,7 @@ func (j *Job) GetJobVersions(args *structs.JobVersionsRequest,
defer metrics.MeasureSince([]string{"nomad", "job", "get_job_versions"}, time.Now())
// Check for read-job permissions
if aclObj, err := j.srv.resolveToken(args.SecretID); err != nil {
if aclObj, err := j.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if aclObj != nil && !aclObj.AllowNsOp(args.RequestNamespace(), acl.NamespaceCapabilityReadJob) {
return structs.ErrPermissionDenied
@@ -759,7 +759,7 @@ func (j *Job) List(args *structs.JobListRequest,
defer metrics.MeasureSince([]string{"nomad", "job", "list"}, time.Now())
// Check for list-job permissions
if aclObj, err := j.srv.resolveToken(args.SecretID); err != nil {
if aclObj, err := j.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if aclObj != nil && !aclObj.AllowNsOp(args.RequestNamespace(), acl.NamespaceCapabilityListJobs) {
return structs.ErrPermissionDenied
@@ -820,7 +820,7 @@ func (j *Job) Allocations(args *structs.JobSpecificRequest,
defer metrics.MeasureSince([]string{"nomad", "job", "allocations"}, time.Now())
// Check for read-job permissions
if aclObj, err := j.srv.resolveToken(args.SecretID); err != nil {
if aclObj, err := j.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if aclObj != nil && !aclObj.AllowNsOp(args.RequestNamespace(), acl.NamespaceCapabilityReadJob) {
return structs.ErrPermissionDenied
@@ -869,7 +869,7 @@ func (j *Job) Evaluations(args *structs.JobSpecificRequest,
defer metrics.MeasureSince([]string{"nomad", "job", "evaluations"}, time.Now())
// Check for read-job permissions
if aclObj, err := j.srv.resolveToken(args.SecretID); err != nil {
if aclObj, err := j.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if aclObj != nil && !aclObj.AllowNsOp(args.RequestNamespace(), acl.NamespaceCapabilityReadJob) {
return structs.ErrPermissionDenied
@@ -911,7 +911,7 @@ func (j *Job) Deployments(args *structs.JobSpecificRequest,
defer metrics.MeasureSince([]string{"nomad", "job", "deployments"}, time.Now())
// Check for read-job permissions
if aclObj, err := j.srv.resolveToken(args.SecretID); err != nil {
if aclObj, err := j.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if aclObj != nil && !aclObj.AllowNsOp(args.RequestNamespace(), acl.NamespaceCapabilityReadJob) {
return structs.ErrPermissionDenied
@@ -953,7 +953,7 @@ func (j *Job) LatestDeployment(args *structs.JobSpecificRequest,
defer metrics.MeasureSince([]string{"nomad", "job", "latest_deployment"}, time.Now())
// Check for read-job permissions
if aclObj, err := j.srv.resolveToken(args.SecretID); err != nil {
if aclObj, err := j.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if aclObj != nil && !aclObj.AllowNsOp(args.RequestNamespace(), acl.NamespaceCapabilityReadJob) {
return structs.ErrPermissionDenied
@@ -1020,7 +1020,7 @@ func (j *Job) Plan(args *structs.JobPlanRequest, reply *structs.JobPlanResponse)
reply.Warnings = structs.MergeMultierrorWarnings(warnings, canonicalizeWarnings)
// Check job submission permissions, which we assume is the same for plan
if aclObj, err := j.srv.resolveToken(args.SecretID); err != nil {
if aclObj, err := j.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if aclObj != nil {
if !aclObj.AllowNsOp(structs.DefaultNamespace, acl.NamespaceCapabilitySubmitJob) {
@@ -1238,7 +1238,7 @@ func (j *Job) Dispatch(args *structs.JobDispatchRequest, reply *structs.JobDispa
defer metrics.MeasureSince([]string{"nomad", "job", "dispatch"}, time.Now())
// Check for submit-job permissions
if aclObj, err := j.srv.resolveToken(args.SecretID); err != nil {
if aclObj, err := j.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if aclObj != nil && !aclObj.AllowNsOp(args.RequestNamespace(), acl.NamespaceCapabilityDispatchJob) {
return structs.ErrPermissionDenied

View File

@@ -389,7 +389,7 @@ func (n *Node) UpdateDrain(args *structs.NodeUpdateDrainRequest,
defer metrics.MeasureSince([]string{"nomad", "client", "update_drain"}, time.Now())
// Check node write permissions
if aclObj, err := n.srv.resolveToken(args.SecretID); err != nil {
if aclObj, err := n.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if aclObj != nil && !aclObj.AllowNodeWrite() {
return structs.ErrPermissionDenied
@@ -451,7 +451,7 @@ func (n *Node) Evaluate(args *structs.NodeEvaluateRequest, reply *structs.NodeUp
defer metrics.MeasureSince([]string{"nomad", "client", "evaluate"}, time.Now())
// Check node write permissions
if aclObj, err := n.srv.resolveToken(args.SecretID); err != nil {
if aclObj, err := n.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if aclObj != nil && !aclObj.AllowNodeWrite() {
return structs.ErrPermissionDenied
@@ -506,7 +506,7 @@ func (n *Node) GetNode(args *structs.NodeSpecificRequest,
defer metrics.MeasureSince([]string{"nomad", "client", "get_node"}, time.Now())
// Check node read permissions
if aclObj, err := n.srv.resolveToken(args.SecretID); err != nil {
if aclObj, err := n.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if aclObj != nil && !aclObj.AllowNodeRead() {
return structs.ErrPermissionDenied
@@ -560,7 +560,7 @@ func (n *Node) GetAllocs(args *structs.NodeSpecificRequest,
defer metrics.MeasureSince([]string{"nomad", "client", "get_allocs"}, time.Now())
// Check node read and namespace job read permissions
aclObj, err := n.srv.resolveToken(args.SecretID)
aclObj, err := n.srv.ResolveToken(args.SecretID)
if err != nil {
return err
}
@@ -817,7 +817,7 @@ func (n *Node) List(args *structs.NodeListRequest,
defer metrics.MeasureSince([]string{"nomad", "client", "list"}, time.Now())
// Check node read permissions
if aclObj, err := n.srv.resolveToken(args.SecretID); err != nil {
if aclObj, err := n.srv.ResolveToken(args.SecretID); err != nil {
return err
} else if aclObj != nil && !aclObj.AllowNodeRead() {
return structs.ErrPermissionDenied