Skip to content

Commit

Permalink
[Feature] Support Apache Ranger as StarRocks RBAC Authorizer (StarRoc…
Browse files Browse the repository at this point in the history
…ks#29154)

Support Apache Ranger as StarRocks RBAC Authorizer

Signed-off-by: HangyuanLiu <[email protected]>
  • Loading branch information
HangyuanLiu authored Aug 23, 2023
1 parent ed4e2d0 commit f934dad
Show file tree
Hide file tree
Showing 20 changed files with 1,909 additions and 7 deletions.
7 changes: 7 additions & 0 deletions fe/fe-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -808,6 +808,13 @@ under the License.
<scope>test</scope>
</dependency>

<!-- https://mvnrepository.com/artifact/org.apache.ranger/ranger-plugins-common -->
<dependency>
<groupId>org.apache.ranger</groupId>
<artifactId>ranger-plugins-common</artifactId>
<version>2.4.0</version>
</dependency>

</dependencies>

<build>
Expand Down
3 changes: 3 additions & 0 deletions fe/fe-core/src/main/java/com/starrocks/common/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -2468,4 +2468,7 @@ public class Config extends ConfigBase {
*/
@ConfField(mutable = true)
public static int primary_key_disk_schedule_time = 3600; // 1h

@ConfField(mutable = true)
public static String access_control = "native";
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@

package com.starrocks.privilege;

import com.starrocks.analysis.Expr;
import com.starrocks.analysis.TableName;
import com.starrocks.catalog.Database;
import com.starrocks.catalog.Function;
import com.starrocks.catalog.Type;
import com.starrocks.qe.ConnectContext;
import com.starrocks.sql.ast.UserIdentity;

import java.util.Set;
Expand Down Expand Up @@ -130,4 +133,12 @@ default void checkStorageVolumeAction(UserIdentity currentUser, Set<Long> roleId
default void checkAnyActionOnStorageVolume(UserIdentity currentUser, Set<Long> roleIds, String storageVolume) {
AccessDeniedException.reportAccessDenied("ANY", ObjectType.STORAGE_VOLUME, storageVolume);
}

default Expr getColumnMaskingPolicy(ConnectContext currentUser, TableName tableName, String columnName, Type type) {
return null;
}

default Expr getRowAccessPolicy(ConnectContext currentUser, TableName tableName) {
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,45 @@

package com.starrocks.privilege;

import com.starrocks.catalog.InternalCatalog;
import com.starrocks.sql.analyzer.AuthorizerStmtVisitor;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class AccessControlProvider {
protected final AuthorizerStmtVisitor privilegeCheckerVisitor;
protected final AccessControl accessControl;
public final Map<String, AccessControl> catalogToAccessControl;

public AccessControlProvider(AuthorizerStmtVisitor privilegeCheckerVisitor, AccessControl accessControl) {
this.privilegeCheckerVisitor = privilegeCheckerVisitor;
this.accessControl = accessControl;

this.catalogToAccessControl = new ConcurrentHashMap<>();
this.catalogToAccessControl.put(InternalCatalog.DEFAULT_INTERNAL_CATALOG_NAME, accessControl);
}

public AuthorizerStmtVisitor getPrivilegeCheckerVisitor() {
return privilegeCheckerVisitor;
}

public AccessControl getAccessControlOrDefault(String catalogName) {
return this.accessControl;
if (catalogName == null) {
return catalogToAccessControl.get(InternalCatalog.DEFAULT_INTERNAL_CATALOG_NAME);
}

AccessControl catalogAccessController = catalogToAccessControl.get(catalogName);
if (catalogAccessController != null) {
return catalogAccessController;
} else {
return catalogToAccessControl.get(InternalCatalog.DEFAULT_INTERNAL_CATALOG_NAME);
}
}

public void setAccessControl(String catalog, AccessControl accessControl) {
catalogToAccessControl.put(catalog, accessControl);
}

public void removeAccessControl(String catalog) {
catalogToAccessControl.remove(catalog);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ public String name() {
}
}

// ANY is not in VALID_PRIVILEGE_TYPE, ANY is not a Privilege Type that users can use directly
public static final PrivilegeType ANY = new PrivilegeType(0, "ANY");

public static final PrivilegeType GRANT = new PrivilegeType(1, "GRANT");
public static final PrivilegeType NODE = new PrivilegeType(2, "NODE");
public static final PrivilegeType OPERATE = new PrivilegeType(3, "OPERATE");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright 2021-present StarRocks, Inc. All rights reserved.
//
// Licensed 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
//
// https://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 com.starrocks.privilege.ranger;

import com.starrocks.catalog.MaterializedView;
import com.starrocks.sql.ast.UserIdentity;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.ranger.plugin.policyengine.RangerAccessRequestImpl;
import org.apache.ranger.plugin.policyengine.RangerAccessResourceImpl;

import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

public class RangerStarRocksAccessRequest extends RangerAccessRequestImpl {
private static final Logger LOG = LogManager.getLogger(MaterializedView.class);

private RangerStarRocksAccessRequest() {
}

public static RangerStarRocksAccessRequest createAccessRequest(RangerAccessResourceImpl resource, UserIdentity user,
String accessType) {
UserGroupInformation ugi = UserGroupInformation.createRemoteUser(user.getQualifiedUser());
String[] groups = ugi.getGroupNames();
Set<String> userGroups = null;
if (groups != null && groups.length > 0) {
userGroups = new HashSet<>(Arrays.asList(groups));
}
RangerStarRocksAccessRequest request = new RangerStarRocksAccessRequest();
request.setUser(user.getQualifiedUser());
request.setUserGroups(userGroups);
request.setAccessType(accessType);
request.setResource(resource);
request.setClientIPAddress(user.getHost());
request.setClientType("starrocks");
request.setClusterName("starrocks");
request.setAccessTime(new Date());

LOG.debug("RangerStarRocksAccessRequest | " + request.toString());

return request;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// Copyright 2021-present StarRocks, Inc. All rights reserved.
//
// Licensed 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
//
// https://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 com.starrocks.privilege.ranger;

import com.starrocks.analysis.Expr;
import com.starrocks.analysis.SlotRef;
import com.starrocks.analysis.TableName;
import com.starrocks.catalog.Column;
import com.starrocks.catalog.InternalCatalog;
import com.starrocks.common.Config;
import com.starrocks.qe.ConnectContext;
import com.starrocks.sql.analyzer.Authorizer;
import com.starrocks.sql.ast.QueryStatement;
import com.starrocks.sql.ast.Relation;
import com.starrocks.sql.ast.SelectList;
import com.starrocks.sql.ast.SelectListItem;
import com.starrocks.sql.ast.SelectRelation;
import com.starrocks.sql.ast.TableRelation;
import com.starrocks.sql.ast.ViewRelation;
import com.starrocks.sql.parser.NodePosition;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class SecurityPolicyRewriteRule {
public static QueryStatement buildView(ConnectContext context, Relation relation, TableName tableName) {
if (!Config.access_control.equals("ranger") &&
(tableName.getCatalog() == null
|| tableName.getCatalog().equals(InternalCatalog.DEFAULT_INTERNAL_CATALOG_NAME))) {
return null;
}

if (relation instanceof TableRelation && ((TableRelation) relation).isSyncMVQuery()) {
return null;
}

List<Column> columns;
if (relation instanceof ViewRelation) {
ViewRelation viewRelation = (ViewRelation) relation;
columns = viewRelation.getView().getBaseSchema();
} else if (relation instanceof TableRelation) {
TableRelation tableRelation = (TableRelation) relation;
columns = tableRelation.getTable().getBaseSchema();
} else {
return null;
}

boolean hasPolicy = false;
List<SelectListItem> selectListItemList = new ArrayList<>();
for (Column column : columns) {
Expr maskingExpr = Authorizer.getColumnMaskingPolicy(
context, tableName, column.getName(), column.getType());

if (maskingExpr != null) {
hasPolicy = true;
selectListItemList.add(new SelectListItem(maskingExpr, column.getName(), NodePosition.ZERO));
} else {
selectListItemList.add(new SelectListItem(new SlotRef(tableName, column.getName()), column.getName(),
NodePosition.ZERO));
}
}

Expr rowAccessExpr = Authorizer.getRowAccessPolicy(context, tableName);
if (rowAccessExpr != null) {
hasPolicy = true;
}

if (!hasPolicy) {
return null;
}

SelectRelation selectRelation = new SelectRelation(
new SelectList(selectListItemList, false),
relation,
rowAccessExpr,
null,
null);
selectRelation.setOrderBy(Collections.emptyList());
return new QueryStatement(selectRelation);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright 2021-present StarRocks, Inc. All rights reserved.
//
// Licensed 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
//
// https://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 com.starrocks.privilege.ranger.hive;

public enum HiveAccessType {
NONE, CREATE, ALTER, DROP, INDEX, LOCK, SELECT, UPDATE, USE, READ, WRITE, ALL, SERVICEADMIN, TEMPUDFADMIN;
}
Loading

0 comments on commit f934dad

Please sign in to comment.