/
RangerOzoneAuthorizer.java
202 lines (176 loc) · 7.56 KB
/
RangerOzoneAuthorizer.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.ranger.authorization.ozone.authorizer;
import com.google.common.collect.Sets;
import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer;
import org.apache.hadoop.ozone.security.acl.IOzoneObj;
import org.apache.hadoop.ozone.security.acl.OzoneObj;
import org.apache.hadoop.ozone.security.acl.RequestContext;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.ranger.audit.provider.MiscUtil;
import org.apache.ranger.plugin.audit.RangerDefaultAuditHandler;
import org.apache.ranger.plugin.policyengine.RangerAccessRequestImpl;
import org.apache.ranger.plugin.policyengine.RangerAccessResourceImpl;
import org.apache.ranger.plugin.policyengine.RangerAccessResult;
import org.apache.ranger.plugin.service.RangerBasePlugin;
import org.apache.ranger.plugin.util.RangerPerfTracer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date;
public class RangerOzoneAuthorizer implements IAccessAuthorizer {
public static final String ACCESS_TYPE_READ = "read";
public static final String ACCESS_TYPE_WRITE = "write";
public static final String ACCESS_TYPE_CREATE = "create";
public static final String ACCESS_TYPE_LIST = "list";
public static final String ACCESS_TYPE_DELETE = "delete";
public static final String ACCESS_TYPE_READ_ACL = "read_acl";
public static final String ACCESS_TYPE_WRITE_ACL = "write_acl";
public static final String KEY_RESOURCE_VOLUME = "volume";
public static final String KEY_RESOURCE_BUCKET = "bucket";
public static final String KEY_RESOURCE_KEY = "key";
private static final Logger PERF_OZONEAUTH_REQUEST_LOG = RangerPerfTracer.getPerfLogger("ozoneauth.request");
private static final Logger LOG = LoggerFactory.getLogger(RangerOzoneAuthorizer.class);
private static volatile RangerBasePlugin rangerPlugin = null;
RangerDefaultAuditHandler auditHandler = null;
public RangerOzoneAuthorizer() {
rangerPlugin = new RangerBasePlugin("ozone", "ozone");
rangerPlugin.init(); // this will initialize policy engine and policy refresher
auditHandler = new RangerDefaultAuditHandler();
rangerPlugin.setResultProcessor(auditHandler);
}
@Override
public boolean checkAccess(IOzoneObj ozoneObject, RequestContext context) {
boolean returnValue = false;
if (ozoneObject == null) {
LOG.error("Ozone object is null!!");
return returnValue;
}
OzoneObj ozoneObj = (OzoneObj) ozoneObject;
UserGroupInformation ugi = context.getClientUgi();
ACLType operation = context.getAclRights();
String resource = ozoneObj.getPath();
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerOzoneAuthorizer.checkAccess with operation = " + operation + ", resource = " +
resource + ", store type = " + OzoneObj.StoreType.values() + ", ugi = " + ugi + ", ip = " +
context.getIp() + ", resourceType = " + ozoneObj.getResourceType() + ")");
}
if (rangerPlugin == null) {
MiscUtil.logErrorMessageByInterval(LOG,
"Authorizer is still not initialized");
return returnValue;
}
//TODO: If sorce type is S3 and resource is volume, then allow it by default
if (ozoneObj.getStoreType() == OzoneObj.StoreType.S3 && ozoneObj.getResourceType() == OzoneObj.ResourceType.VOLUME) {
if (LOG.isDebugEnabled()) {
LOG.debug("If store type is s3 and resource is volume, then we allow it by default! Returning true");
}
LOG.warn("Allowing access by default since source type is S3 and resource type is Volume!!");
return true;
}
RangerPerfTracer perf = null;
if (RangerPerfTracer.isPerfTraceEnabled(PERF_OZONEAUTH_REQUEST_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_OZONEAUTH_REQUEST_LOG, "RangerOzoneAuthorizer.authorize(resource=" + resource + ")");
}
Date eventTime = new Date();
String accessType = mapToRangerAccessType(operation);
if (accessType == null) {
MiscUtil.logErrorMessageByInterval(LOG,
"Unsupported access type. operation=" + operation) ;
LOG.error("Unsupported access type. operation=" + operation + ", resource=" + resource);
return returnValue;
}
String action = accessType;
String clusterName = rangerPlugin.getClusterName();
RangerAccessRequestImpl rangerRequest = new RangerAccessRequestImpl();
rangerRequest.setUser(ugi.getShortUserName());
rangerRequest.setUserGroups(Sets.newHashSet(ugi.getGroupNames()));
rangerRequest.setClientIPAddress(context.getIp().getHostAddress());
rangerRequest.setRemoteIPAddress(context.getIp().getHostAddress());
rangerRequest.setAccessTime(eventTime);
RangerAccessResourceImpl rangerResource = new RangerAccessResourceImpl();
rangerRequest.setResource(rangerResource);
rangerRequest.setAccessType(accessType);
rangerRequest.setAction(action);
rangerRequest.setRequestData(resource);
rangerRequest.setClusterName(clusterName);
if (ozoneObj.getResourceType() == OzoneObj.ResourceType.VOLUME) {
rangerResource.setValue(KEY_RESOURCE_VOLUME, ozoneObj.getVolumeName());
} else if (ozoneObj.getResourceType() == OzoneObj.ResourceType.BUCKET || ozoneObj.getResourceType() == OzoneObj.ResourceType.KEY) {
if (ozoneObj.getStoreType() == OzoneObj.StoreType.S3) {
rangerResource.setValue(KEY_RESOURCE_VOLUME, "s3Vol");
} else {
rangerResource.setValue(KEY_RESOURCE_VOLUME, ozoneObj.getVolumeName());
}
rangerResource.setValue(KEY_RESOURCE_BUCKET, ozoneObj.getBucketName());
if (ozoneObj.getResourceType() == OzoneObj.ResourceType.KEY) {
rangerResource.setValue(KEY_RESOURCE_KEY, ozoneObj.getKeyName());
}
} else {
LOG.error("Unsupported resource = " + resource);
MiscUtil.logErrorMessageByInterval(LOG, "Unsupported resource type " + ozoneObj.getResourceType() + " for resource = " + resource
+ ", request=" + rangerRequest);
return returnValue;
}
try {
RangerAccessResult result = rangerPlugin
.isAccessAllowed(rangerRequest);
if (result == null) {
LOG.error("Ranger Plugin returned null. Returning false");
} else {
returnValue = result.getIsAllowed();
}
} catch (Throwable t) {
LOG.error("Error while calling isAccessAllowed(). request="
+ rangerRequest, t);
}
RangerPerfTracer.log(perf);
if (LOG.isDebugEnabled()) {
LOG.debug("rangerRequest=" + rangerRequest + ", return="
+ returnValue);
}
return returnValue;
}
private String mapToRangerAccessType(ACLType operation) {
String rangerAccessType = null;
switch (operation) {
case READ:
rangerAccessType = ACCESS_TYPE_READ;
break;
case WRITE:
rangerAccessType = ACCESS_TYPE_WRITE;
break;
case CREATE:
rangerAccessType = ACCESS_TYPE_CREATE;
break;
case DELETE:
rangerAccessType = ACCESS_TYPE_DELETE;
break;
case LIST:
rangerAccessType = ACCESS_TYPE_LIST;
break;
case READ_ACL:
rangerAccessType = ACCESS_TYPE_READ_ACL;
break;
case WRITE_ACL:
rangerAccessType = ACCESS_TYPE_WRITE_ACL;
break;
}
return rangerAccessType;
}
}