Beispiel #1
0
func (r *RBACAuthorizer) Authorize(attr authorizer.Attributes) error {
	if r.superUser != "" && attr.GetUserName() == r.superUser {
		return nil
	}

	userInfo := &user.DefaultInfo{
		Name:   attr.GetUserName(),
		Groups: attr.GetGroups(),
	}

	ctx := api.WithNamespace(api.WithUser(api.NewContext(), userInfo), attr.GetNamespace())

	// Frame the authorization request as a privilege escalation check.
	var requestedRule rbac.PolicyRule
	if attr.IsResourceRequest() {
		requestedRule = rbac.PolicyRule{
			Verbs:         []string{attr.GetVerb()},
			APIGroups:     []string{attr.GetAPIGroup()}, // TODO(ericchiang): add api version here too?
			Resources:     []string{attr.GetResource()},
			ResourceNames: []string{attr.GetName()},
		}
	} else {
		requestedRule = rbac.PolicyRule{
			NonResourceURLs: []string{attr.GetPath()},
		}
	}

	return validation.ConfirmNoEscalation(ctx, r.authorizationRuleResolver, []rbac.PolicyRule{requestedRule})
}
Beispiel #2
0
func (s *Storage) Create(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
	if u, ok := api.UserFrom(ctx); ok {
		if s.superUser != "" && u.GetName() == s.superUser {
			return s.StandardStorage.Create(ctx, obj)
		}

		// system:masters is special because the API server uses it for privileged loopback connections
		// therefore we know that a member of system:masters can always do anything
		for _, group := range u.GetGroups() {
			if group == user.SystemPrivilegedGroup {
				return s.StandardStorage.Create(ctx, obj)
			}
		}
	}

	clusterRoleBinding := obj.(*rbac.ClusterRoleBinding)
	rules, err := s.ruleResolver.GetRoleReferenceRules(ctx, clusterRoleBinding.RoleRef, clusterRoleBinding.Namespace)
	if err != nil {
		return nil, err
	}
	if err := validation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil {
		return nil, errors.NewForbidden(groupResource, clusterRoleBinding.Name, err)
	}
	return s.StandardStorage.Create(ctx, obj)
}
Beispiel #3
0
func (r *RBACAuthorizer) Authorize(attr authorizer.Attributes) (bool, string, error) {
	if r.superUser != "" && attr.GetUser() != nil && attr.GetUser().GetName() == r.superUser {
		return true, "", nil
	}

	ctx := api.WithNamespace(api.WithUser(api.NewContext(), attr.GetUser()), attr.GetNamespace())

	// Frame the authorization request as a privilege escalation check.
	var requestedRule rbac.PolicyRule
	if attr.IsResourceRequest() {
		requestedRule = rbac.PolicyRule{
			Verbs:         []string{attr.GetVerb()},
			APIGroups:     []string{attr.GetAPIGroup()}, // TODO(ericchiang): add api version here too?
			Resources:     []string{attr.GetResource()},
			ResourceNames: []string{attr.GetName()},
		}
	} else {
		requestedRule = rbac.PolicyRule{
			Verbs:           []string{attr.GetVerb()},
			NonResourceURLs: []string{attr.GetPath()},
		}
	}

	// TODO(nhlfr): Try to find more lightweight way to check attributes than escalation checks.
	err := validation.ConfirmNoEscalation(ctx, r.authorizationRuleResolver, []rbac.PolicyRule{requestedRule})
	if err != nil {
		return false, err.Error(), nil
	}

	return true, "", nil
}
Beispiel #4
0
func (s *Storage) Create(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
	if rbacregistry.EscalationAllowed(ctx, s.superUser) {
		return s.StandardStorage.Create(ctx, obj)
	}

	clusterRole := obj.(*rbac.ClusterRole)
	rules := clusterRole.Rules
	if err := validation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil {
		return nil, errors.NewForbidden(groupResource, clusterRole.Name, err)
	}
	return s.StandardStorage.Create(ctx, obj)
}
Beispiel #5
0
func (s *Storage) Create(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
	if user, ok := api.UserFrom(ctx); ok {
		if s.superUser != "" && user.GetName() == s.superUser {
			return s.StandardStorage.Create(ctx, obj)
		}
	}

	clusterRole := obj.(*rbac.ClusterRole)
	rules := clusterRole.Rules
	if err := validation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil {
		return nil, errors.NewForbidden(groupResource, clusterRole.Name, err)
	}
	return s.StandardStorage.Create(ctx, obj)
}
Beispiel #6
0
func (s *Storage) Create(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
	if rbacregistry.EscalationAllowed(ctx) {
		return s.StandardStorage.Create(ctx, obj)
	}

	clusterRoleBinding := obj.(*rbac.ClusterRoleBinding)
	rules, err := s.ruleResolver.GetRoleReferenceRules(clusterRoleBinding.RoleRef, clusterRoleBinding.Namespace)
	if err != nil {
		return nil, err
	}
	if err := validation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil {
		return nil, errors.NewForbidden(groupResource, clusterRoleBinding.Name, err)
	}
	return s.StandardStorage.Create(ctx, obj)
}
Beispiel #7
0
func (s *Storage) Update(ctx api.Context, name string, obj rest.UpdatedObjectInfo) (runtime.Object, bool, error) {
	if rbacregistry.EscalationAllowed(ctx, s.superUser) {
		return s.StandardStorage.Update(ctx, name, obj)
	}

	nonEscalatingInfo := wrapUpdatedObjectInfo(obj, func(ctx api.Context, obj runtime.Object, oldObj runtime.Object) (runtime.Object, error) {
		clusterRole := obj.(*rbac.ClusterRole)

		rules := clusterRole.Rules
		if err := validation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil {
			return nil, errors.NewForbidden(groupResource, clusterRole.Name, err)
		}
		return obj, nil
	})

	return s.StandardStorage.Update(ctx, name, nonEscalatingInfo)
}
Beispiel #8
0
func (s *Storage) Create(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
	if user, ok := api.UserFrom(ctx); ok {
		if s.superUser != "" && user.GetName() == s.superUser {
			return s.StandardStorage.Create(ctx, obj)
		}
	}

	roleBinding := obj.(*rbac.RoleBinding)
	rules, err := s.ruleResolver.GetRoleReferenceRules(ctx, roleBinding.RoleRef, roleBinding.Namespace)
	if err != nil {
		return nil, err
	}
	if err := validation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil {
		return nil, errors.NewForbidden(groupResource, roleBinding.Name, err)
	}
	return s.StandardStorage.Create(ctx, obj)
}
Beispiel #9
0
func (s *Storage) Update(ctx api.Context, name string, obj rest.UpdatedObjectInfo) (runtime.Object, bool, error) {
	if user, ok := api.UserFrom(ctx); ok {
		if s.superUser != "" && user.GetName() == s.superUser {
			return s.StandardStorage.Update(ctx, name, obj)
		}
	}

	nonEscalatingInfo := wrapUpdatedObjectInfo(obj, func(ctx api.Context, obj runtime.Object, oldObj runtime.Object) (runtime.Object, error) {
		role := obj.(*rbac.Role)

		rules := role.Rules
		if err := validation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil {
			return nil, errors.NewForbidden(groupResource, role.Name, err)
		}
		return obj, nil
	})

	return s.StandardStorage.Update(ctx, name, nonEscalatingInfo)
}
Beispiel #10
0
func (s *Storage) Update(ctx api.Context, name string, obj rest.UpdatedObjectInfo) (runtime.Object, bool, error) {
	if rbacregistry.EscalationAllowed(ctx, s.superUser) {
		return s.StandardStorage.Update(ctx, name, obj)
	}

	nonEscalatingInfo := wrapUpdatedObjectInfo(obj, func(ctx api.Context, obj runtime.Object, oldObj runtime.Object) (runtime.Object, error) {
		roleBinding := obj.(*rbac.RoleBinding)

		rules, err := s.ruleResolver.GetRoleReferenceRules(roleBinding.RoleRef, roleBinding.Namespace)
		if err != nil {
			return nil, err
		}
		if err := validation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil {
			return nil, errors.NewForbidden(groupResource, roleBinding.Name, err)
		}
		return obj, nil
	})

	return s.StandardStorage.Update(ctx, name, nonEscalatingInfo)
}