...
1
16
17 package rbac
18
19 import (
20 "context"
21 "fmt"
22
23 "k8s.io/apimachinery/pkg/runtime/schema"
24 utilruntime "k8s.io/apimachinery/pkg/util/runtime"
25 "k8s.io/apiserver/pkg/authentication/user"
26 "k8s.io/apiserver/pkg/authorization/authorizer"
27 genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
28 "k8s.io/kubernetes/pkg/apis/rbac"
29 )
30
31
32 func EscalationAllowed(ctx context.Context) bool {
33 u, ok := genericapirequest.UserFrom(ctx)
34 if !ok {
35 return false
36 }
37
38
39
40 for _, group := range u.GetGroups() {
41 if group == user.SystemPrivilegedGroup {
42 return true
43 }
44 }
45
46 return false
47 }
48
49 var roleResources = map[schema.GroupResource]bool{
50 rbac.SchemeGroupVersion.WithResource("clusterroles").GroupResource(): true,
51 rbac.SchemeGroupVersion.WithResource("roles").GroupResource(): true,
52 }
53
54
55 func RoleEscalationAuthorized(ctx context.Context, a authorizer.Authorizer) bool {
56 if a == nil {
57 return false
58 }
59
60 user, ok := genericapirequest.UserFrom(ctx)
61 if !ok {
62 return false
63 }
64
65 requestInfo, ok := genericapirequest.RequestInfoFrom(ctx)
66 if !ok {
67 return false
68 }
69
70 if !requestInfo.IsResourceRequest {
71 return false
72 }
73
74 requestResource := schema.GroupResource{Group: requestInfo.APIGroup, Resource: requestInfo.Resource}
75 if !roleResources[requestResource] {
76 return false
77 }
78
79 attrs := authorizer.AttributesRecord{
80 User: user,
81 Verb: "escalate",
82 APIGroup: requestInfo.APIGroup,
83 APIVersion: "*",
84 Resource: requestInfo.Resource,
85 Name: requestInfo.Name,
86 Namespace: requestInfo.Namespace,
87 ResourceRequest: true,
88 }
89
90 decision, _, err := a.Authorize(ctx, attrs)
91 if err != nil {
92 utilruntime.HandleError(fmt.Errorf(
93 "error authorizing user %#v to escalate %#v named %q in namespace %q: %v",
94 user, requestResource, requestInfo.Name, requestInfo.Namespace, err,
95 ))
96 }
97 return decision == authorizer.DecisionAllow
98 }
99
100
101 func BindingAuthorized(ctx context.Context, roleRef rbac.RoleRef, bindingNamespace string, a authorizer.Authorizer) bool {
102 if a == nil {
103 return false
104 }
105
106 user, ok := genericapirequest.UserFrom(ctx)
107 if !ok {
108 return false
109 }
110
111 attrs := authorizer.AttributesRecord{
112 User: user,
113 Verb: "bind",
114
115
116
117 Namespace: bindingNamespace,
118 ResourceRequest: true,
119 }
120
121
122
123 switch roleRef.Kind {
124 case "ClusterRole":
125 attrs.APIGroup = roleRef.APIGroup
126 attrs.APIVersion = "*"
127 attrs.Resource = "clusterroles"
128 attrs.Name = roleRef.Name
129 case "Role":
130 attrs.APIGroup = roleRef.APIGroup
131 attrs.APIVersion = "*"
132 attrs.Resource = "roles"
133 attrs.Name = roleRef.Name
134 default:
135 return false
136 }
137
138 decision, _, err := a.Authorize(ctx, attrs)
139 if err != nil {
140 utilruntime.HandleError(fmt.Errorf(
141 "error authorizing user %#v to bind %#v in namespace %s: %v",
142 user, roleRef, bindingNamespace, err,
143 ))
144 }
145 return decision == authorizer.DecisionAllow
146 }
147
View as plain text