Repository: sentry Updated Branches: refs/heads/master acdb36df3 -> 03236072c
SENTRY-2157: Update audit log to grant/revoke owner privileges (Sergio Pena, reviewed by Na Li, Arjun Mishra) Project: http://git-wip-us.apache.org/repos/asf/sentry/repo Commit: http://git-wip-us.apache.org/repos/asf/sentry/commit/03236072 Tree: http://git-wip-us.apache.org/repos/asf/sentry/tree/03236072 Diff: http://git-wip-us.apache.org/repos/asf/sentry/diff/03236072 Branch: refs/heads/master Commit: 03236072c606d305fb4a9975fdfa7bbfbdbfb82e Parents: acdb36d Author: Sergio Pena <[email protected]> Authored: Thu Aug 9 08:54:01 2018 -0500 Committer: Sergio Pena <[email protected]> Committed: Thu Aug 9 08:56:51 2018 -0500 ---------------------------------------------------------------------- .../thrift/SentryPolicyStoreProcessor.java | 133 ++++------ .../provider/db/audit/SentryAuditLogger.java | 261 +++++++++++++++++++ .../db/log/entity/JsonLogEntityFactory.java | 53 +++- .../provider/db/log/util/CommandUtil.java | 47 +++- .../sentry/provider/db/log/util/Constants.java | 2 + .../db/log/entity/TestJsonLogEntityFactory.java | 8 +- 6 files changed, 407 insertions(+), 97 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/sentry/blob/03236072/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/api/service/thrift/SentryPolicyStoreProcessor.java ---------------------------------------------------------------------- diff --git a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/api/service/thrift/SentryPolicyStoreProcessor.java b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/api/service/thrift/SentryPolicyStoreProcessor.java index 00015ef..8a4588c 100644 --- a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/api/service/thrift/SentryPolicyStoreProcessor.java +++ b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/api/service/thrift/SentryPolicyStoreProcessor.java @@ -51,8 +51,7 @@ import org.apache.sentry.core.common.exception.SentryNoSuchObjectException; import org.apache.sentry.provider.db.SentryPolicyStorePlugin; import org.apache.sentry.provider.db.SentryPolicyStorePlugin.SentryPluginException; import org.apache.sentry.core.common.exception.SentryThriftAPIMismatchException; -import org.apache.sentry.provider.db.log.entity.JsonLogEntity; -import org.apache.sentry.provider.db.log.entity.JsonLogEntityFactory; +import org.apache.sentry.provider.db.audit.SentryAuditLogger; import org.apache.sentry.provider.db.log.util.Constants; import org.apache.sentry.provider.db.service.persistent.SentryStoreInterface; import org.apache.sentry.core.common.utils.PolicyStoreConstants.PolicyStoreServerConfig; @@ -87,6 +86,7 @@ import static org.apache.sentry.hdfs.Updateable.Update; public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface { private static final Logger LOGGER = Logger.getLogger(SentryPolicyStoreProcessor.class); private static final Logger AUDIT_LOGGER = Logger.getLogger(Constants.AUDIT_LOGGER_NAME); + private static final Map<TSentryPrincipalType, SentryPrincipalType> mapOwnerType = ImmutableMap.of( TSentryPrincipalType.ROLE, SentryPrincipalType.ROLE, TSentryPrincipalType.USER, SentryPrincipalType.USER @@ -101,6 +101,7 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface { private final Timer hmsWaitTimer = SentryMetrics.getInstance(). getTimer(name(SentryPolicyStoreProcessor.class, "hms", "wait")); + private final SentryAuditLogger audit; private List<SentryPolicyStorePlugin> sentryPlugins = new LinkedList<SentryPolicyStorePlugin>(); @@ -112,6 +113,7 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface { this.sentryStore = store; this.notificationHandlerInvoker = new NotificationHandlerInvoker(conf, createHandlers(conf)); + this.audit = new SentryAuditLogger(conf); adminGroups = ImmutableSet.copyOf(toTrimedLower(Sets.newHashSet(conf.getStrings( ServerConfig.ADMIN_GROUPS, new String[]{})))); Iterable<String> pluginClasses = ConfUtilties.CLASS_SPLITTER @@ -236,14 +238,7 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface { timerContext.stop(); } - try { - AUDIT_LOGGER.info(JsonLogEntityFactory.getInstance() - .createJsonLogEntity(request, response, conf).toJsonFormatLog()); - } catch (Exception e) { - // if any exception, log the exception. - String msg = "Error creating audit log for create role: " + e.getMessage(); - LOGGER.error(msg, e); - } + audit.onCreateRole(request, response); return response; } @@ -310,17 +305,7 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface { timerContext.stop(); } - try { - Set<JsonLogEntity> jsonLogEntitys = JsonLogEntityFactory.getInstance().createJsonLogEntitys( - request, response, conf); - for (JsonLogEntity jsonLogEntity : jsonLogEntitys) { - AUDIT_LOGGER.info(jsonLogEntity.toJsonFormatLog()); - } - } catch (Exception e) { - // if any exception, log the exception. - String msg = "Error creating audit log for grant privilege to role: " + e.getMessage(); - LOGGER.error(msg, e); - } + audit.onGrantRolePrivilege(request, response); return response; } @@ -399,17 +384,7 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface { timerContext.stop(); } - try { - Set<JsonLogEntity> jsonLogEntitys = JsonLogEntityFactory.getInstance().createJsonLogEntitys( - request, response, conf); - for (JsonLogEntity jsonLogEntity : jsonLogEntitys) { - AUDIT_LOGGER.info(jsonLogEntity.toJsonFormatLog()); - } - } catch (Exception e) { - // if any exception, log the exception. - String msg = "Error creating audit log for revoke privilege from role: " + e.getMessage(); - LOGGER.error(msg, e); - } + audit.onRevokeRolePrivilege(request, response); return response; } @@ -460,14 +435,7 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface { timerContext.stop(); } - try { - AUDIT_LOGGER.info(JsonLogEntityFactory.getInstance() - .createJsonLogEntity(request, response, conf).toJsonFormatLog()); - } catch (Exception e) { - // if any exception, log the exception. - String msg = "Error creating audit log for drop role: " + e.getMessage(); - LOGGER.error(msg, e); - } + audit.onDropRole(request, response); return response; } @@ -519,14 +487,7 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface { timerContext.stop(); } - try { - AUDIT_LOGGER.info(JsonLogEntityFactory.getInstance() - .createJsonLogEntity(request, response, conf).toJsonFormatLog()); - } catch (Exception e) { - // if any exception, log the exception. - String msg = "Error creating audit log for add role to group: " + e.getMessage(); - LOGGER.error(msg, e); - } + audit.onGrantRoleToGroup(request, response); return response; } @@ -562,14 +523,7 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface { timerContext.stop(); } - try { - AUDIT_LOGGER.info(JsonLogEntityFactory.getInstance() - .createJsonLogEntity(request, response, conf).toJsonFormatLog()); - } catch (Exception e) { - // if any exception, log the exception. - String msg = "Error creating audit log for add role to user: " + e.getMessage(); - LOGGER.error(msg, e); - } + audit.onGrantRoleToUser(request, response); return response; } @@ -606,14 +560,7 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface { timerContext.stop(); } - try { - AUDIT_LOGGER.info(JsonLogEntityFactory.getInstance() - .createJsonLogEntity(request, response, conf).toJsonFormatLog()); - } catch (Exception e) { - // if any exception, log the exception. - String msg = "Error creating audit log for delete role from user: " + e.getMessage(); - LOGGER.error(msg, e); - } + audit.onRevokeRoleFromUser(request, response); return response; } @@ -666,14 +613,7 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface { timerContext.stop(); } - try { - AUDIT_LOGGER.info(JsonLogEntityFactory.getInstance() - .createJsonLogEntity(request, response, conf).toJsonFormatLog()); - } catch (Exception e) { - // if any exception, log the exception. - String msg = "Error creating audit log for delete role from group: " + e.getMessage(); - LOGGER.error(msg, e); - } + audit.onRevokeRoleFromGroup(request, response); return response; } @@ -1354,7 +1294,7 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface { @Override public TSentryHmsEventNotificationResponse sentry_notify_hms_event - (TSentryHmsEventNotification request) throws TException{ + (TSentryHmsEventNotification request) throws TException { TSentryHmsEventNotificationResponse response = new TSentryHmsEventNotificationResponse(); EventType eventType = EventType.valueOf(request.getEventType()); try (Timer.Context timerContext = sentryMetrics.notificationProcessTimer.time()) { @@ -1509,8 +1449,8 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface { return; } - SentryPrincipalType entityType = getSentryPrincipalType(request.getOwnerType()); - if (entityType == null) { + SentryPrincipalType principalType = getSentryPrincipalType(request.getOwnerType()); + if (principalType == null) { String error = "Invalid owner type : " + request.getEventType(); LOGGER.error(error); throw new SentryInvalidInputException(error); @@ -1533,11 +1473,23 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface { default: LOGGER.error("Invalid owner Type"); } - // Grants owner privilege to the entity - sentryStore.alterSentryGrantOwnerPrivilege(request.getOwnerName(), entityType, - ownerPrivilege, privilegesUpdateMap.get(ownerPrivilege)); + + // Grants owner privilege to the principal + try { + sentryStore.alterSentryGrantOwnerPrivilege(request.getOwnerName(), principalType, + ownerPrivilege, privilegesUpdateMap.get(ownerPrivilege)); + + audit.onGrantOwnerPrivilege(Status.OK(), request.getRequestorUserName(), + request.getOwnerType(), request.getOwnerName(), request.getAuthorizable()); + } catch (Exception e) { + String msg = "Owner privilege for " + request.getAuthorizable() + " could not be granted: " + e.getMessage(); + audit.onGrantOwnerPrivilege(Status.RuntimeError(msg, e), request.getRequestorUserName(), + request.getOwnerType(), request.getOwnerName(), request.getAuthorizable()); + + throw e; + } + //TODO Implement notificationHandlerInvoker API for granting user priv and invoke it. - //TODO Implement Audit Log API's and invoke them here. } /** @@ -1561,8 +1513,8 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface { return; } - SentryPrincipalType entityType = getSentryPrincipalType(request.getOwnerType()); - if(entityType == null ) { + SentryPrincipalType principalType = getSentryPrincipalType(request.getOwnerType()); + if(principalType == null ) { String error = "Invalid owner type : " + request.getEventType(); LOGGER.error(error); throw new SentryInvalidInputException(error); @@ -1590,11 +1542,24 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface { } } } + // Revokes old owner privileges and grants owner privilege for new owner. - sentryStore.updateOwnerPrivilege(request.getAuthorizable(), request.getOwnerName(), - entityType, updateList); + try { + sentryStore.updateOwnerPrivilege(request.getAuthorizable(), request.getOwnerName(), + principalType, updateList); + + audit.onTransferOwnerPrivilege(Status.OK(), request.getRequestorUserName(), + request.getOwnerType(), request.getOwnerName(), request.getAuthorizable()); + } catch (Exception e) { + String msg = "Owner privilege for " + request.getAuthorizable() + " could not be granted: " + e.getMessage(); + + audit.onTransferOwnerPrivilege(Status.RuntimeError(msg, e), request.getRequestorUserName(), + request.getOwnerType(), request.getOwnerName(), request.getAuthorizable()); + + throw e; + } + //TODO Implement notificationHandlerInvoker API for granting user priv and invoke it. - //TODO Implement Audit Log API's and invoke them here. } /** http://git-wip-us.apache.org/repos/asf/sentry/blob/03236072/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/audit/SentryAuditLogger.java ---------------------------------------------------------------------- diff --git a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/audit/SentryAuditLogger.java b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/audit/SentryAuditLogger.java new file mode 100644 index 0000000..748a528 --- /dev/null +++ b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/audit/SentryAuditLogger.java @@ -0,0 +1,261 @@ +/** + * 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.sentry.provider.db.audit; + +import java.util.Collection; +import org.apache.hadoop.conf.Configuration; +import org.apache.sentry.api.service.thrift.TAlterSentryRoleAddGroupsRequest; +import org.apache.sentry.api.service.thrift.TAlterSentryRoleAddGroupsResponse; +import org.apache.sentry.api.service.thrift.TAlterSentryRoleAddUsersRequest; +import org.apache.sentry.api.service.thrift.TAlterSentryRoleAddUsersResponse; +import org.apache.sentry.api.service.thrift.TAlterSentryRoleDeleteGroupsRequest; +import org.apache.sentry.api.service.thrift.TAlterSentryRoleDeleteGroupsResponse; +import org.apache.sentry.api.service.thrift.TAlterSentryRoleDeleteUsersRequest; +import org.apache.sentry.api.service.thrift.TAlterSentryRoleDeleteUsersResponse; +import org.apache.sentry.api.service.thrift.TAlterSentryRoleGrantPrivilegeRequest; +import org.apache.sentry.api.service.thrift.TAlterSentryRoleGrantPrivilegeResponse; +import org.apache.sentry.api.service.thrift.TAlterSentryRoleRevokePrivilegeRequest; +import org.apache.sentry.api.service.thrift.TAlterSentryRoleRevokePrivilegeResponse; +import org.apache.sentry.api.service.thrift.TCreateSentryRoleRequest; +import org.apache.sentry.api.service.thrift.TCreateSentryRoleResponse; +import org.apache.sentry.api.service.thrift.TDropSentryRoleRequest; +import org.apache.sentry.api.service.thrift.TDropSentryRoleResponse; +import org.apache.sentry.api.service.thrift.TSentryAuthorizable; +import org.apache.sentry.api.service.thrift.TSentryPrincipalType; +import org.apache.sentry.provider.db.log.entity.JsonLogEntity; +import org.apache.sentry.provider.db.log.entity.JsonLogEntityFactory; +import org.apache.sentry.provider.db.log.util.Constants; +import org.apache.sentry.service.thrift.TSentryResponseStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class has methods to help log Sentry actions or events that need to be printed in a proper + * format for Auditing log tools. + */ +public class SentryAuditLogger { + private static final Logger ERROR_LOGGER = LoggerFactory.getLogger(SentryAuditLogger.class); + private static final Logger AUDIT_LOGGER = LoggerFactory.getLogger(Constants.AUDIT_LOGGER_NAME); + private static final JsonLogEntityFactory JSON_LOG_ENTITY = JsonLogEntityFactory.getInstance(); + + /** + * Configuration values required to create all JSON log entities. + */ + private final Configuration conf; + + /** + * Constructs a {@link SentryAuditLogger} with the desired configuration passed as a parameter. + * + * @param conf The configuration values necessary to create JSON log entities. + */ + public SentryAuditLogger(Configuration conf) { + this.conf = conf; + } + + /** + * Creates an audit log for the create role event. + * + * @param request The create role request received by the Sentry server. + * @param response The create role response generated by the Sentry server. + */ + public void onCreateRole(TCreateSentryRoleRequest request, TCreateSentryRoleResponse response) { + try { + info(JSON_LOG_ENTITY.createJsonLogEntity(request, response, conf)); + } catch (Exception e) { + String msg = "Cannot generate an audit log for creating a role: " + e.getMessage(); + ERROR_LOGGER.error(msg, e); + } + } + + /** + * Creates an audit log for the drop role event. + * + * @param request The drop role request received by the Sentry server. + * @param response The drop role response generated by the Sentry server. + */ + public void onDropRole(TDropSentryRoleRequest request, TDropSentryRoleResponse response) { + try { + info(JSON_LOG_ENTITY.createJsonLogEntity(request, response, conf)); + } catch (Exception e) { + String msg = "Cannot generate an audit log for creating a role: " + e.getMessage(); + ERROR_LOGGER.error(msg, e); + } + } + + /** + * Creates an audit log for the grant role privilege event. + * + * @param request The grant role privilege request received by the Sentry server. + * @param response The grant role privilege response generated by the Sentry server. + */ + public void onGrantRolePrivilege(TAlterSentryRoleGrantPrivilegeRequest request, TAlterSentryRoleGrantPrivilegeResponse response) { + try { + info(JSON_LOG_ENTITY.createJsonLogEntities(request, response, conf)); + } catch (Exception e) { + String msg = "Cannot generate an audit log for grant role privilege: " + e.getMessage(); + ERROR_LOGGER.error(msg, e); + } + } + + /** + * Creates an audit log for the grant owner privilege event. + * + * @param status The response status of Sentry when granting the privilege. + * @param requestorUserName The user name on behalf this grant is made + * @param ownerType The principal type who to grant the owner privilege. + * @param ownerName The name of the owner who to grant the owner privilege. + * @param authorizable The authorizable object where to grant the owner privilege. + */ + public void onGrantOwnerPrivilege(TSentryResponseStatus status, String requestorUserName, + TSentryPrincipalType ownerType, String ownerName, TSentryAuthorizable authorizable) { + try { + info(JSON_LOG_ENTITY.createJsonLogEntity(Constants.OPERATION_GRANT_OWNER_PRIVILEGE, + Constants.OBJECT_TYPE_PRINCIPAL, requestorUserName, status, authorizable, + ownerType, ownerName, conf)); + } catch (Exception e) { + String msg = "Cannot generate an audit log for grant owner privilege: " + e.getMessage(); + ERROR_LOGGER.error(msg, e); + } + } + + /** + * Creates an audit log for the transfer owner privilege event. + * + * @param status The response status of Sentry when transferring the privilege. + * @param requestorUserName The user name on behalf this transfer is made + * @param ownerType The principal type who to transfer the owner privilege. + * @param ownerName The name of the owner who to transfer the owner privilege. + * @param authorizable The authorizable object where to transfer the owner privilege. + */ + public void onTransferOwnerPrivilege(TSentryResponseStatus status, String requestorUserName, + TSentryPrincipalType ownerType, String ownerName, TSentryAuthorizable authorizable) { + try { + info(JSON_LOG_ENTITY.createJsonLogEntity(Constants.OPERATION_TRANSFER_OWNER_PRIVILEGE, + Constants.OBJECT_TYPE_PRINCIPAL, requestorUserName, status, authorizable, + ownerType, ownerName, conf)); + } catch (Exception e) { + String msg = "Cannot generate an audit log for grant owner privilege: " + e.getMessage(); + ERROR_LOGGER.error(msg, e); + } + } + + /** + * Creates an audit log for the revoke role privilege event. + * + * @param request The revoke role privilege request received by the Sentry server. + * @param response The revoke role privilege response generated by the Sentry server. + */ + public void onRevokeRolePrivilege(TAlterSentryRoleRevokePrivilegeRequest request, TAlterSentryRoleRevokePrivilegeResponse response) { + try { + info(JSON_LOG_ENTITY.createJsonLogEntities(request, response, conf)); + } catch (Exception e) { + String msg = "Cannot generate an audit log for revoke role privilege: " + e.getMessage(); + ERROR_LOGGER.error(msg, e); + } + } + + /** + * Creates an audit log for the revoke user owner privilege event. + * + * @param requestorUserName The user name on behalf this revoke is made + * @param status The response status of Sentry when revoking the privilege. + * @param userName The name of the user who to revoke the owner privilege. + * @param authorizable The authorizable object where to revoke the owner privilege. + */ + public void onRevokeUserOwnerPrivilege(String requestorUserName, TSentryResponseStatus status, + String userName, TSentryAuthorizable authorizable) { + try { + info(JSON_LOG_ENTITY.createJsonLogEntity(Constants.OPERATION_REVOKE_PRIVILEGE, + Constants.OBJECT_TYPE_PRINCIPAL, requestorUserName, status, authorizable, + TSentryPrincipalType.USER, userName, conf)); + } catch (Exception e) { + String msg = "Cannot generate an audit log for grant user owner privilege: " + e.getMessage(); + ERROR_LOGGER.error(msg, e); + } + } + + /** + * Creates an audit log for the role add groups event. + * + * @param request The role add groups request received by the Sentry server. + * @param response The role add groups response generated by the Sentry server. + */ + public void onGrantRoleToGroup(TAlterSentryRoleAddGroupsRequest request, TAlterSentryRoleAddGroupsResponse response) { + try { + info(JSON_LOG_ENTITY.createJsonLogEntity(request, response, conf)); + } catch (Exception e) { + String msg = "Cannot generate an audit log for adding groups to a role: " + e.getMessage(); + ERROR_LOGGER.error(msg, e); + } + } + + /** + * Creates an audit log for the role delete groups event. + * + * @param request The role delete groups request received by the Sentry server. + * @param response The role delete groups response generated by the Sentry server. + */ + public void onRevokeRoleFromGroup(TAlterSentryRoleDeleteGroupsRequest request, TAlterSentryRoleDeleteGroupsResponse response) { + try { + info(JSON_LOG_ENTITY.createJsonLogEntity(request, response, conf)); + } catch (Exception e) { + String msg = "Cannot generate an audit log for deleting groups from a role: " + e.getMessage(); + ERROR_LOGGER.error(msg, e); + } + } + + /** + * Creates an audit log for the role add users event. + * + * @param request The role add users request received by the Sentry server. + * @param response The role add users response generated by the Sentry server. + */ + public void onGrantRoleToUser(TAlterSentryRoleAddUsersRequest request, TAlterSentryRoleAddUsersResponse response) { + try { + info(JSON_LOG_ENTITY.createJsonLogEntity(request, response, conf)); + } catch (Exception e) { + String msg = "Cannot generate an audit log for adding users to a role: " + e.getMessage(); + ERROR_LOGGER.error(msg, e); + } + } + + /** + * Creates an audit log for the role delete users event. + * + * @param request The role delete users request received by the Sentry server. + * @param response The role delete users response generated by the Sentry server. + */ + public void onRevokeRoleFromUser(TAlterSentryRoleDeleteUsersRequest request, TAlterSentryRoleDeleteUsersResponse response) { + try { + info(JSON_LOG_ENTITY.createJsonLogEntity(request, response, conf)); + } catch (Exception e) { + String msg = "Cannot generate an audit log for deleting users from a role: " + e.getMessage(); + ERROR_LOGGER.error(msg, e); + } + } + + private void info(Collection<JsonLogEntity> jsonLogEntities) throws Exception { + for (JsonLogEntity jsonLogEntity : jsonLogEntities) { + info(jsonLogEntity); + } + } + + private void info(JsonLogEntity jsonLogEntity) throws Exception { + AUDIT_LOGGER.info(jsonLogEntity.toJsonFormatLog()); + } +} http://git-wip-us.apache.org/repos/asf/sentry/blob/03236072/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/log/entity/JsonLogEntityFactory.java ---------------------------------------------------------------------- diff --git a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/log/entity/JsonLogEntityFactory.java b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/log/entity/JsonLogEntityFactory.java index 61becce..7d64480 100644 --- a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/log/entity/JsonLogEntityFactory.java +++ b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/log/entity/JsonLogEntityFactory.java @@ -26,6 +26,8 @@ import java.util.Set; import org.apache.hadoop.conf.Configuration; import org.apache.sentry.api.generic.thrift.TAuthorizable; +import org.apache.sentry.api.service.thrift.TSentryAuthorizable; +import org.apache.sentry.api.service.thrift.TSentryPrincipalType; import org.apache.sentry.provider.db.log.util.CommandUtil; import org.apache.sentry.provider.db.log.util.Constants; import org.apache.sentry.api.service.thrift.TAlterSentryRoleAddGroupsRequest; @@ -88,7 +90,7 @@ public final class JsonLogEntityFactory { } // log entity for hive/impala grant privilege - public Set<JsonLogEntity> createJsonLogEntitys( + public Set<JsonLogEntity> createJsonLogEntities( TAlterSentryRoleGrantPrivilegeRequest request, TAlterSentryRoleGrantPrivilegeResponse response, Configuration conf) { ImmutableSet.Builder<JsonLogEntity> setBuilder = ImmutableSet.builder(); @@ -114,7 +116,7 @@ public final class JsonLogEntityFactory { } // log entity for hive/impala revoke privilege - public Set<JsonLogEntity> createJsonLogEntitys( + public Set<JsonLogEntity> createJsonLogEntities( TAlterSentryRoleRevokePrivilegeRequest request, TAlterSentryRoleRevokePrivilegeResponse response, Configuration conf) { ImmutableSet.Builder<JsonLogEntity> setBuilder = ImmutableSet.builder(); @@ -164,6 +166,25 @@ public final class JsonLogEntityFactory { return hamle; } + public JsonLogEntity createJsonLogEntity(String operationType, String objectType, + String requestorUserName, TSentryResponseStatus status, TSentryAuthorizable authorizable, + TSentryPrincipalType ownerType, String ownerName, Configuration conf) { + DBAuditMetadataLogEntity hamle = createCommonHAMLE(conf, status, requestorUserName, + operationType, objectType); + + if (Constants.OPERATION_GRANT_OWNER_PRIVILEGE.equals(operationType)) { + hamle.setOperationText(CommandUtil.createCmdForImplicitGrantOwnerPrivilege(ownerType, ownerName, authorizable)); + } else if (Constants.OPERATION_TRANSFER_OWNER_PRIVILEGE.equals(operationType)) { + hamle.setOperationText(CommandUtil.createCmdForImplicitTransferOwnerPrivilege(ownerType, ownerName, authorizable)); + } else { + hamle.setOperationText("Unknown operation"); + } + + hamle.setDatabaseName(authorizable.getDb()); + hamle.setTableName(authorizable.getTable()); + return hamle; + } + private String getGroupsStr(Iterator<TSentryGroup> iter) { StringBuilder groups = new StringBuilder(""); if (iter != null) { @@ -322,7 +343,15 @@ public final class JsonLogEntityFactory { private DBAuditMetadataLogEntity createCommonHAMLE(Configuration conf, TSentryResponseStatus responseStatus, String userName, String requestClassName) { DBAuditMetadataLogEntity hamle = new DBAuditMetadataLogEntity(); - setCommAttrForAMLE(hamle, conf, responseStatus, userName, requestClassName); + setCommAttrForAMLE(hamle, conf, responseStatus, userName, toOperationType(requestClassName), + toObjectType(requestClassName)); + return hamle; + } + + private DBAuditMetadataLogEntity createCommonHAMLE(Configuration conf, + TSentryResponseStatus responseStatus, String userName, String operationType, String objectType) { + DBAuditMetadataLogEntity hamle = new DBAuditMetadataLogEntity(); + setCommAttrForAMLE(hamle, conf, responseStatus, userName, operationType, objectType); return hamle; } @@ -330,22 +359,30 @@ public final class JsonLogEntityFactory { TSentryResponseStatus responseStatus, String userName, String requestClassName, String component) { GMAuditMetadataLogEntity gmamle = new GMAuditMetadataLogEntity(); - setCommAttrForAMLE(gmamle, conf, responseStatus, userName, requestClassName); + setCommAttrForAMLE(gmamle, conf, responseStatus, userName, toOperationType(requestClassName), + toObjectType(requestClassName)); gmamle.setComponent(component); return gmamle; } private void setCommAttrForAMLE(AuditMetadataLogEntity amle, Configuration conf, - TSentryResponseStatus responseStatus, String userName, String requestClassName) { + TSentryResponseStatus responseStatus, String userName, String operationType, String objectType) { amle.setUserName(userName); amle.setServiceName(conf.get(ServerConfig.SENTRY_SERVICE_NAME, ServerConfig.SENTRY_SERVICE_NAME_DEFAULT).trim()); amle.setImpersonator(ThriftUtil.getImpersonator()); amle.setIpAddress(ThriftUtil.getIpAddress()); - amle.setOperation(Constants.requestTypeToOperationMap.get(requestClassName)); + amle.setOperation(operationType); amle.setEventTime(Long.toString(System.currentTimeMillis())); amle.setAllowed(isAllowed(responseStatus)); - amle.setObjectType(Constants.requestTypeToObjectTypeMap - .get(requestClassName)); + amle.setObjectType(objectType); + } + + private String toOperationType(String className) { + return Constants.requestTypeToOperationMap.get(className); + } + + private String toObjectType(String className) { + return Constants.requestTypeToObjectTypeMap.get(className); } } http://git-wip-us.apache.org/repos/asf/sentry/blob/03236072/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/log/util/CommandUtil.java ---------------------------------------------------------------------- diff --git a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/log/util/CommandUtil.java b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/log/util/CommandUtil.java index 6479a60..11c00a1 100644 --- a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/log/util/CommandUtil.java +++ b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/log/util/CommandUtil.java @@ -24,6 +24,8 @@ import java.util.Enumeration; import java.util.List; import java.util.Set; +import org.apache.sentry.api.service.thrift.TSentryAuthorizable; +import org.apache.sentry.api.service.thrift.TSentryPrincipalType; import org.apache.sentry.core.model.db.AccessConstants; import org.apache.sentry.api.generic.thrift.TAuthorizable; import org.apache.sentry.api.common.ApiConstants.PrivilegeScope; @@ -36,7 +38,6 @@ import org.datanucleus.util.StringUtils; import com.google.common.annotations.VisibleForTesting; public final class CommandUtil { - public CommandUtil() { // Make constructor private to avoid instantiation } @@ -212,6 +213,50 @@ public final class CommandUtil { return sb.toString(); } + public static String createCmdForImplicitGrantOwnerPrivilege(TSentryPrincipalType ownerType, + String ownerName, TSentryAuthorizable authorizable) { + StringBuilder sb = new StringBuilder(); + + sb.append("OWNER privilege on"); + if (StringUtils.isEmpty(authorizable.getTable())) { + sb.append(" database "); + sb.append(authorizable.getDb()); + } else { + sb.append(" table "); + sb.append(authorizable.getDb()); + sb.append("."); + sb.append(authorizable.getTable()); + } + + sb.append(" is granted to "); + sb.append(ownerType.toString()).append(": "); + sb.append(ownerName); + + return sb.toString(); + } + + public static String createCmdForImplicitTransferOwnerPrivilege(TSentryPrincipalType ownerType, + String ownerName, TSentryAuthorizable authorizable) { + StringBuilder sb = new StringBuilder(); + + sb.append("OWNER privilege on"); + if (StringUtils.isEmpty(authorizable.getTable())) { + sb.append(" database "); + sb.append(authorizable.getDb()); + } else { + sb.append(" table "); + sb.append(authorizable.getDb()); + sb.append("."); + sb.append(authorizable.getTable()); + } + + sb.append(" is transferred to "); + sb.append(ownerType.toString()).append(": "); + sb.append(ownerName); + + return sb.toString(); + } + // Check if the given IP is one of the local IP. @VisibleForTesting public static boolean assertIPInAuditLog(String ipInAuditLog) throws Exception { http://git-wip-us.apache.org/repos/asf/sentry/blob/03236072/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/log/util/Constants.java ---------------------------------------------------------------------- diff --git a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/log/util/Constants.java b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/log/util/Constants.java index 6e91f8b..f174e4a 100644 --- a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/log/util/Constants.java +++ b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/log/util/Constants.java @@ -50,6 +50,8 @@ public final class Constants { public static final String OPERATION_DELETE_ROLE_USER = "DELETE_ROLE_FROM_USER"; public static final String OPERATION_GRANT_PRIVILEGE = "GRANT_PRIVILEGE"; public static final String OPERATION_REVOKE_PRIVILEGE = "REVOKE_PRIVILEGE"; + public static final String OPERATION_GRANT_OWNER_PRIVILEGE = "GRANT_OWNER_PRIVILEGE"; + public static final String OPERATION_TRANSFER_OWNER_PRIVILEGE = "TRANSFER_OWNER_PRIVILEGE"; public static final String OBJECT_TYPE_PRINCIPAL = "PRINCIPAL"; public static final String OBJECT_TYPE_ROLE = "ROLE"; http://git-wip-us.apache.org/repos/asf/sentry/blob/03236072/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/provider/db/log/entity/TestJsonLogEntityFactory.java ---------------------------------------------------------------------- diff --git a/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/provider/db/log/entity/TestJsonLogEntityFactory.java b/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/provider/db/log/entity/TestJsonLogEntityFactory.java index 307f38e..da6ac5d 100644 --- a/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/provider/db/log/entity/TestJsonLogEntityFactory.java +++ b/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/provider/db/log/entity/TestJsonLogEntityFactory.java @@ -124,7 +124,7 @@ public class TestJsonLogEntityFactory { response.setStatus(Status.OK()); DBAuditMetadataLogEntity amle = new DBAuditMetadataLogEntity(); Set<JsonLogEntity> amles = JsonLogEntityFactory - .getInstance().createJsonLogEntitys(request, response, conf); + .getInstance().createJsonLogEntities(request, response, conf); assertEquals(amles.size(),1); amle = (DBAuditMetadataLogEntity) amles.iterator().next(); @@ -139,7 +139,7 @@ public class TestJsonLogEntityFactory { request.setPrivileges(privileges); response.setStatus(Status.InvalidInput("", null)); amles = JsonLogEntityFactory.getInstance() - .createJsonLogEntitys(request, response, conf); + .createJsonLogEntities(request, response, conf); assertEquals(amles.size(),1); amle = (DBAuditMetadataLogEntity) amles.iterator().next(); @@ -163,7 +163,7 @@ public class TestJsonLogEntityFactory { response.setStatus(Status.OK()); DBAuditMetadataLogEntity amle = new DBAuditMetadataLogEntity(); Set<JsonLogEntity> amles = JsonLogEntityFactory - .getInstance().createJsonLogEntitys(request, response, conf); + .getInstance().createJsonLogEntities(request, response, conf); assertEquals(amles.size(),1); amle = (DBAuditMetadataLogEntity) amles.iterator().next(); @@ -178,7 +178,7 @@ public class TestJsonLogEntityFactory { request.setPrivileges(privileges); response.setStatus(Status.InvalidInput("", null)); amles = JsonLogEntityFactory.getInstance() - .createJsonLogEntitys(request, response, conf); + .createJsonLogEntities(request, response, conf); assertEquals(amles.size(),1); amle = (DBAuditMetadataLogEntity) amles.iterator().next();
