ACCUMULO-1681 - Rolling in match (after merging)
Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/9a2041d5 Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/9a2041d5 Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/9a2041d5 Branch: refs/heads/master Commit: 9a2041d56019e253b08732c9d931e99981f41660 Parents: e04fd19 Author: John Vines <[email protected]> Authored: Mon Oct 28 19:10:15 2013 -0400 Committer: John Vines <[email protected]> Committed: Mon Oct 28 19:10:15 2013 -0400 ---------------------------------------------------------------------- .../accumulo/core/constraints/Constraint.java | 4 + .../core/iterators/system/VisibilityFilter.java | 4 +- .../core/security/AuthorizationContainer.java | 26 + .../accumulo/core/security/Authorizations.java | 3 +- .../core/security/VisibilityConstraint.java | 2 +- .../core/security/VisibilityEvaluator.java | 20 +- .../core/security/VisibilityEvaluatorTest.java | 2 +- .../server/security/SecurityOperation.java | 203 +-- .../server/security/handler/Authorizor.java | 8 + .../server/security/handler/ZKAuthorizor.java | 12 + .../server/tabletserver/TabletServer.java | 1260 +++++++++--------- .../randomwalk/security/WalkingSecurity.java | 13 + 12 files changed, 824 insertions(+), 733 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/accumulo/blob/9a2041d5/core/src/main/java/org/apache/accumulo/core/constraints/Constraint.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/accumulo/core/constraints/Constraint.java b/core/src/main/java/org/apache/accumulo/core/constraints/Constraint.java index c7fb070..89b2dc8 100644 --- a/core/src/main/java/org/apache/accumulo/core/constraints/Constraint.java +++ b/core/src/main/java/org/apache/accumulo/core/constraints/Constraint.java @@ -20,6 +20,7 @@ import java.util.List; import org.apache.accumulo.core.data.KeyExtent; import org.apache.accumulo.core.data.Mutation; +import org.apache.accumulo.core.security.AuthorizationContainer; import org.apache.accumulo.core.security.Authorizations; /** @@ -46,7 +47,10 @@ public interface Constraint { String getUser(); + @Deprecated Authorizations getAuthorizations(); + + AuthorizationContainer getAuthorizationsContainer(); } /** http://git-wip-us.apache.org/repos/asf/accumulo/blob/9a2041d5/core/src/main/java/org/apache/accumulo/core/iterators/system/VisibilityFilter.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/accumulo/core/iterators/system/VisibilityFilter.java b/core/src/main/java/org/apache/accumulo/core/iterators/system/VisibilityFilter.java index 092efe9..15c33fa 100644 --- a/core/src/main/java/org/apache/accumulo/core/iterators/system/VisibilityFilter.java +++ b/core/src/main/java/org/apache/accumulo/core/iterators/system/VisibilityFilter.java @@ -36,6 +36,7 @@ public class VisibilityFilter extends Filter { protected Text defaultVisibility; protected LRUMap cache; protected Text tmpVis; + protected Authorizations authorizations; private static final Logger log = Logger.getLogger(VisibilityFilter.class); @@ -44,6 +45,7 @@ public class VisibilityFilter extends Filter { public VisibilityFilter(SortedKeyValueIterator<Key,Value> iterator, Authorizations authorizations, byte[] defaultVisibility) { setSource(iterator); this.ve = new VisibilityEvaluator(authorizations); + this.authorizations = authorizations; this.defaultVisibility = new Text(defaultVisibility); this.cache = new LRUMap(1000); this.tmpVis = new Text(); @@ -51,7 +53,7 @@ public class VisibilityFilter extends Filter { @Override public SortedKeyValueIterator<Key,Value> deepCopy(IteratorEnvironment env) { - return new VisibilityFilter(getSource().deepCopy(env), ve.getAuthorizations(), TextUtil.getBytes(defaultVisibility)); + return new VisibilityFilter(getSource().deepCopy(env), authorizations, TextUtil.getBytes(defaultVisibility)); } @Override http://git-wip-us.apache.org/repos/asf/accumulo/blob/9a2041d5/core/src/main/java/org/apache/accumulo/core/security/AuthorizationContainer.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/accumulo/core/security/AuthorizationContainer.java b/core/src/main/java/org/apache/accumulo/core/security/AuthorizationContainer.java new file mode 100644 index 0000000..041bf3c --- /dev/null +++ b/core/src/main/java/org/apache/accumulo/core/security/AuthorizationContainer.java @@ -0,0 +1,26 @@ +/* + * 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.accumulo.core.security; + +import org.apache.accumulo.core.data.ByteSequence; + +public interface AuthorizationContainer { + /** + * Checks for the existence of this UTF-8 encoded authorization. + */ + public boolean contains(ByteSequence auth); +} http://git-wip-us.apache.org/repos/asf/accumulo/blob/9a2041d5/core/src/main/java/org/apache/accumulo/core/security/Authorizations.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/accumulo/core/security/Authorizations.java b/core/src/main/java/org/apache/accumulo/core/security/Authorizations.java index 47a5475..5cecefb 100644 --- a/core/src/main/java/org/apache/accumulo/core/security/Authorizations.java +++ b/core/src/main/java/org/apache/accumulo/core/security/Authorizations.java @@ -34,7 +34,7 @@ import org.apache.accumulo.core.util.ArgumentChecker; import org.apache.accumulo.core.util.ByteBufferUtil; import org.apache.commons.codec.binary.Base64; -public class Authorizations implements Iterable<byte[]>, Serializable { +public class Authorizations implements Iterable<byte[]>, Serializable, AuthorizationContainer { private static final long serialVersionUID = 1L; @@ -223,6 +223,7 @@ public class Authorizations implements Iterable<byte[]>, Serializable { /** * Checks for the existence of this UTF-8 encoded authorization. */ + @Override public boolean contains(ByteSequence auth) { return auths.contains(auth); } http://git-wip-us.apache.org/repos/asf/accumulo/blob/9a2041d5/core/src/main/java/org/apache/accumulo/core/security/VisibilityConstraint.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/accumulo/core/security/VisibilityConstraint.java b/core/src/main/java/org/apache/accumulo/core/security/VisibilityConstraint.java index c8b33ba..ae29cc7 100644 --- a/core/src/main/java/org/apache/accumulo/core/security/VisibilityConstraint.java +++ b/core/src/main/java/org/apache/accumulo/core/security/VisibilityConstraint.java @@ -60,7 +60,7 @@ public class VisibilityConstraint implements Constraint { try { if (ve == null) - ve = new VisibilityEvaluator(env.getAuthorizations()); + ve = new VisibilityEvaluator(env); if (!ve.evaluate(new ColumnVisibility(cv))) return Collections.singletonList(new Short((short) 2)); http://git-wip-us.apache.org/repos/asf/accumulo/blob/9a2041d5/core/src/main/java/org/apache/accumulo/core/security/VisibilityEvaluator.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/accumulo/core/security/VisibilityEvaluator.java b/core/src/main/java/org/apache/accumulo/core/security/VisibilityEvaluator.java index 549af76..45b595f 100644 --- a/core/src/main/java/org/apache/accumulo/core/security/VisibilityEvaluator.java +++ b/core/src/main/java/org/apache/accumulo/core/security/VisibilityEvaluator.java @@ -17,12 +17,12 @@ package org.apache.accumulo.core.security; import java.util.ArrayList; -import java.util.Collection; +import org.apache.accumulo.core.constraints.Constraint.Environment; import org.apache.accumulo.core.security.ColumnVisibility.Node; public class VisibilityEvaluator { - private Authorizations auths; + private AuthorizationContainer auths; static Authorizations escape(Authorizations auths) { ArrayList<byte[]> retAuths = new ArrayList<byte[]>(auths.getAuthorizations().size()); @@ -53,25 +53,21 @@ public class VisibilityEvaluator { escapedAuth[0] = '"'; escapedAuth[escapedAuth.length - 1] = '"'; } - + auth = escapedAuth; } return auth; } - - VisibilityEvaluator(Collection<byte[]> authorizations) { - this(new Authorizations(authorizations)); + + VisibilityEvaluator(Environment env) { + this.auths = env.getAuthorizationsContainer(); } /** * The VisibilityEvaluator computes a trie from the given Authorizations, that ColumnVisibility expressions can be evaluated against. */ public VisibilityEvaluator(Authorizations authorizations) { - this.auths = escape(authorizations); - } - - public Authorizations getAuthorizations() { - return new Authorizations(auths.getAuthorizations()); + this.auths = escape((Authorizations) authorizations); } public boolean evaluate(ColumnVisibility visibility) throws VisibilityParseException { @@ -79,7 +75,7 @@ public class VisibilityEvaluator { } private final boolean evaluate(final byte[] expression, final Node root) throws VisibilityParseException { - if(expression.length == 0) + if (expression.length == 0) return true; switch (root.type) { case TERM: http://git-wip-us.apache.org/repos/asf/accumulo/blob/9a2041d5/core/src/test/java/org/apache/accumulo/core/security/VisibilityEvaluatorTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/accumulo/core/security/VisibilityEvaluatorTest.java b/core/src/test/java/org/apache/accumulo/core/security/VisibilityEvaluatorTest.java index 2d70ce6..ee4d2ee 100644 --- a/core/src/test/java/org/apache/accumulo/core/security/VisibilityEvaluatorTest.java +++ b/core/src/test/java/org/apache/accumulo/core/security/VisibilityEvaluatorTest.java @@ -30,7 +30,7 @@ public class VisibilityEvaluatorTest { @Test public void testVisibilityEvaluator() throws VisibilityParseException { - VisibilityEvaluator ct = new VisibilityEvaluator(ByteArraySet.fromStrings("one", "two", "three", "four")); + VisibilityEvaluator ct = new VisibilityEvaluator(new Authorizations(ByteArraySet.fromStrings("one", "two", "three", "four"))); // test for empty vis assertTrue(ct.evaluate(new ColumnVisibility(new byte[0]))); http://git-wip-us.apache.org/repos/asf/accumulo/blob/9a2041d5/server/src/main/java/org/apache/accumulo/server/security/SecurityOperation.java ---------------------------------------------------------------------- diff --git a/server/src/main/java/org/apache/accumulo/server/security/SecurityOperation.java b/server/src/main/java/org/apache/accumulo/server/security/SecurityOperation.java index 19d107b..666d3e7 100644 --- a/server/src/main/java/org/apache/accumulo/server/security/SecurityOperation.java +++ b/server/src/main/java/org/apache/accumulo/server/security/SecurityOperation.java @@ -59,21 +59,21 @@ import org.apache.log4j.Logger; */ public class SecurityOperation { private static final Logger log = Logger.getLogger(SecurityOperationsImpl.class); - + protected Authorizor authorizor; protected Authenticator authenticator; protected PermissionHandler permHandle; private static String rootUserName = null; private final ZooCache zooCache; private final String ZKUserPath; - + protected static SecurityOperation instance; - + public static synchronized SecurityOperation getInstance() { String instanceId = HdfsZooInstance.getInstance().getInstanceID(); return getInstance(instanceId, false); } - + public static synchronized SecurityOperation getInstance(String instanceId, boolean initialize) { if (instance == null) { instance = new SecurityOperation(getAuthorizor(instanceId, initialize), getAuthenticator(instanceId, initialize), getPermHandler(instanceId, initialize), @@ -81,51 +81,51 @@ public class SecurityOperation { } return instance; } - + protected static Authorizor getAuthorizor(String instanceId, boolean initialize) { Authorizor toRet = Property.createInstanceFromPropertyName(ServerConfiguration.getSiteConfiguration(), Property.INSTANCE_SECURITY_AUTHORIZOR, Authorizor.class, ZKAuthorizor.getInstance()); toRet.initialize(instanceId, initialize); return toRet; } - + protected static Authenticator getAuthenticator(String instanceId, boolean initialize) { Authenticator toRet = Property.createInstanceFromPropertyName(ServerConfiguration.getSiteConfiguration(), Property.INSTANCE_SECURITY_AUTHENTICATOR, Authenticator.class, ZKAuthenticator.getInstance()); toRet.initialize(instanceId, initialize); return toRet; } - + protected static PermissionHandler getPermHandler(String instanceId, boolean initialize) { PermissionHandler toRet = Property.createInstanceFromPropertyName(ServerConfiguration.getSiteConfiguration(), Property.INSTANCE_SECURITY_PERMISSION_HANDLER, PermissionHandler.class, ZKPermHandler.getInstance()); toRet.initialize(instanceId, initialize); return toRet; } - + protected SecurityOperation(String instanceId) { ZKUserPath = Constants.ZROOT + "/" + instanceId + "/users"; zooCache = new ZooCache(); } - + public SecurityOperation(Authorizor author, Authenticator authent, PermissionHandler pm, String instanceId) { this(instanceId); authorizor = author; authenticator = authent; permHandle = pm; - + if (!authorizor.validSecurityHandlers(authenticator, pm) || !authenticator.validSecurityHandlers(authorizor, pm) || !permHandle.validSecurityHandlers(authent, author)) throw new RuntimeException(authorizor + ", " + authenticator + ", and " + pm + " do not play nice with eachother. Please choose authentication and authorization mechanisms that are compatible with one another."); } - + public void initializeSecurity(TCredentials credentials, String rootPrincipal, byte[] token) throws AccumuloSecurityException, ThriftSecurityException { authenticate(credentials); - + if (!isSystemUser(credentials)) throw new AccumuloSecurityException(credentials.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED); - + authenticator.initializeSecurity(credentials, rootPrincipal, token); authorizor.initializeSecurity(credentials, rootPrincipal); permHandle.initializeSecurity(credentials, rootPrincipal); @@ -136,21 +136,21 @@ public class SecurityOperation { throw new RuntimeException(e); } } - + public synchronized String getRootUsername() { if (rootUserName == null) rootUserName = new String(zooCache.get(ZKUserPath)); return rootUserName; } - + public boolean isSystemUser(TCredentials credentials) { return SystemCredentials.get().getToken().getClass().getName().equals(credentials.getTokenClassName()); } - + private void authenticate(TCredentials credentials) throws ThriftSecurityException { if (!credentials.getInstanceId().equals(HdfsZooInstance.getInstance().getInstanceID())) throw new ThriftSecurityException(credentials.getPrincipal(), SecurityErrorCode.INVALID_INSTANCEID); - + if (isSystemUser(credentials)) { authenticateSystemUser(credentials); } else { @@ -165,19 +165,19 @@ public class SecurityOperation { } } } - + private void authenticateSystemUser(TCredentials credentials) throws ThriftSecurityException { if (SystemCredentials.get().getToken().equals(credentials.getToken())) throw new ThriftSecurityException(credentials.getPrincipal(), SecurityErrorCode.BAD_CREDENTIALS); } - + public boolean canAskAboutUser(TCredentials credentials, String user) throws ThriftSecurityException { // Authentication done in canPerformSystemActions if (!(canPerformSystemActions(credentials) || credentials.getPrincipal().equals(user))) throw new ThriftSecurityException(credentials.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED); return true; } - + public boolean authenticateUser(TCredentials credentials, TCredentials toAuth) throws ThriftSecurityException { canAskAboutUser(credentials, toAuth.getPrincipal()); // User is already authenticated from canAskAboutUser @@ -190,7 +190,7 @@ public class SecurityOperation { throw e.asThriftException(); } } - + private AuthenticationToken reassembleToken(TCredentials toAuth) throws AccumuloSecurityException { String tokenClass = toAuth.getTokenClassName(); if (authenticator.validTokenClass(tokenClass)) { @@ -198,22 +198,22 @@ public class SecurityOperation { } throw new AccumuloSecurityException(toAuth.getPrincipal(), SecurityErrorCode.INVALID_TOKEN); } - + public Authorizations getUserAuthorizations(TCredentials credentials, String user) throws ThriftSecurityException { authenticate(credentials); - + targetUserExists(user); - + if (!credentials.getPrincipal().equals(user) && !hasSystemPermission(credentials, SystemPermission.SYSTEM, false)) throw new ThriftSecurityException(credentials.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED); - + try { return authorizor.getCachedUserAuthorizations(user); } catch (AccumuloSecurityException e) { throw e.asThriftException(); } } - + public Authorizations getUserAuthorizations(TCredentials credentials) throws ThriftSecurityException { // system user doesn't need record-level authorizations for the tables it reads if (isSystemUser(credentials)) { @@ -222,7 +222,22 @@ public class SecurityOperation { } return getUserAuthorizations(credentials, credentials.getPrincipal()); } - + + public boolean userHasAuthorizations(TCredentials credentials, List<ByteBuffer> list) throws ThriftSecurityException { + authenticate(credentials); + + if (isSystemUser(credentials)) { + // system user doesn't need record-level authorizations for the tables it reads (for now) + return list.isEmpty(); + } + + try { + return authorizor.isValidAuthorizations(credentials.getPrincipal(), list); + } catch (AccumuloSecurityException e) { + throw e.asThriftException(); + } + } + /** * Checks if a user has a system permission * @@ -233,7 +248,7 @@ public class SecurityOperation { return true; return _hasSystemPermission(credentials.getPrincipal(), permission, useCached); } - + /** * Checks if a user has a system permission<br/> * This cannot check if a system user has permission. @@ -243,9 +258,9 @@ public class SecurityOperation { private boolean _hasSystemPermission(String user, SystemPermission permission, boolean useCached) throws ThriftSecurityException { if (user.equals(getRootUsername())) return true; - + targetUserExists(user); - + try { if (useCached) return permHandle.hasCachedSystemPermission(user, permission); @@ -254,7 +269,7 @@ public class SecurityOperation { throw e.asThriftException(); } } - + /** * Checks if a user has a table permission * @@ -265,7 +280,7 @@ public class SecurityOperation { return true; return _hasTablePermission(credentials.getPrincipal(), table, permission, useCached); } - + /** * Checks if a user has a table permission<br/> * This cannot check if a system user has permission. @@ -274,10 +289,10 @@ public class SecurityOperation { */ protected boolean _hasTablePermission(String user, String table, TablePermission permission, boolean useCached) throws ThriftSecurityException { targetUserExists(user); - + if ((table.equals(MetadataTable.ID) || table.equals(RootTable.ID)) && permission.equals(TablePermission.READ)) return true; - + try { if (useCached) return permHandle.hasCachedTablePermission(user, table, permission); @@ -288,7 +303,7 @@ public class SecurityOperation { throw new ThriftSecurityException(user, SecurityErrorCode.TABLE_DOESNT_EXIST); } } - + // some people just aren't allowed to ask about other users; here are those who can ask private boolean canAskAboutOtherUsers(TCredentials credentials, String user) throws ThriftSecurityException { authenticate(credentials); @@ -296,7 +311,7 @@ public class SecurityOperation { || hasSystemPermission(credentials, SystemPermission.CREATE_USER, false) || hasSystemPermission(credentials, SystemPermission.ALTER_USER, false) || hasSystemPermission(credentials, SystemPermission.DROP_USER, false); } - + private void targetUserExists(String user) throws ThriftSecurityException { if (user.equals(getRootUsername())) return; @@ -307,40 +322,40 @@ public class SecurityOperation { throw e.asThriftException(); } } - + public boolean canScan(TCredentials credentials, String table) throws ThriftSecurityException { authenticate(credentials); return hasTablePermission(credentials, table, TablePermission.READ, true); } - + public boolean canScan(TCredentials credentials, String table, TRange range, List<TColumn> columns, List<IterInfo> ssiList, Map<String,Map<String,String>> ssio, List<ByteBuffer> authorizations) throws ThriftSecurityException { return canScan(credentials, table); } - + public boolean canScan(TCredentials credentials, String table, Map<TKeyExtent,List<TRange>> tbatch, List<TColumn> tcolumns, List<IterInfo> ssiList, Map<String,Map<String,String>> ssio, List<ByteBuffer> authorizations) throws ThriftSecurityException { return canScan(credentials, table); } - + public boolean canWrite(TCredentials credentials, String table) throws ThriftSecurityException { authenticate(credentials); return hasTablePermission(credentials, table, TablePermission.WRITE, true); } - + public boolean canConditionallyUpdate(TCredentials credentials, String tableID, List<ByteBuffer> authorizations) throws ThriftSecurityException { - + authenticate(credentials); - + return hasTablePermission(credentials, tableID, TablePermission.WRITE, true) && hasTablePermission(credentials, tableID, TablePermission.READ, true); } - + public boolean canSplitTablet(TCredentials credentials, String table) throws ThriftSecurityException { authenticate(credentials); return hasSystemPermission(credentials, SystemPermission.ALTER_TABLE, false) || hasSystemPermission(credentials, SystemPermission.SYSTEM, false) || hasTablePermission(credentials, table, TablePermission.ALTER_TABLE, false); } - + /** * This is the check to perform any system action. This includes tserver's loading of a tablet, shutting the system down, or altering system properties. */ @@ -348,95 +363,95 @@ public class SecurityOperation { authenticate(credentials); return hasSystemPermission(credentials, SystemPermission.SYSTEM, false); } - + public boolean canFlush(TCredentials c, String tableId) throws ThriftSecurityException { authenticate(c); return hasTablePermission(c, tableId, TablePermission.WRITE, false) || hasTablePermission(c, tableId, TablePermission.ALTER_TABLE, false); } - + public boolean canAlterTable(TCredentials c, String tableId) throws ThriftSecurityException { authenticate(c); return hasTablePermission(c, tableId, TablePermission.ALTER_TABLE, false) || hasSystemPermission(c, SystemPermission.ALTER_TABLE, false); } - + public boolean canCreateTable(TCredentials c, String tableName) throws ThriftSecurityException { return canCreateTable(c); } - + public boolean canCreateTable(TCredentials c) throws ThriftSecurityException { authenticate(c); return hasSystemPermission(c, SystemPermission.CREATE_TABLE, false); } - + public boolean canRenameTable(TCredentials c, String tableId, String oldTableName, String newTableName) throws ThriftSecurityException { authenticate(c); return hasSystemPermission(c, SystemPermission.ALTER_TABLE, false) || hasTablePermission(c, tableId, TablePermission.ALTER_TABLE, false); } - + public boolean canCloneTable(TCredentials c, String tableId, String tableName) throws ThriftSecurityException { authenticate(c); return hasSystemPermission(c, SystemPermission.CREATE_TABLE, false) && hasTablePermission(c, tableId, TablePermission.READ, false); } - + public boolean canDeleteTable(TCredentials c, String tableId) throws ThriftSecurityException { authenticate(c); return hasSystemPermission(c, SystemPermission.DROP_TABLE, false) || hasTablePermission(c, tableId, TablePermission.DROP_TABLE, false); } - + public boolean canOnlineOfflineTable(TCredentials c, String tableId, TableOperation op) throws ThriftSecurityException { authenticate(c); return hasSystemPermission(c, SystemPermission.SYSTEM, false) || hasSystemPermission(c, SystemPermission.ALTER_TABLE, false) || hasTablePermission(c, tableId, TablePermission.ALTER_TABLE, false); } - + public boolean canMerge(TCredentials c, String tableId) throws ThriftSecurityException { authenticate(c); return hasSystemPermission(c, SystemPermission.SYSTEM, false) || hasSystemPermission(c, SystemPermission.ALTER_TABLE, false) || hasTablePermission(c, tableId, TablePermission.ALTER_TABLE, false); } - + public boolean canDeleteRange(TCredentials c, String tableId, String tableName, Text startRow, Text endRow) throws ThriftSecurityException { authenticate(c); return hasSystemPermission(c, SystemPermission.SYSTEM, false) || hasTablePermission(c, tableId, TablePermission.WRITE, false); } - + public boolean canBulkImport(TCredentials c, String tableId, String tableName, String dir, String failDir) throws ThriftSecurityException { return canBulkImport(c, tableId); } - + public boolean canBulkImport(TCredentials c, String tableId) throws ThriftSecurityException { authenticate(c); return hasTablePermission(c, tableId, TablePermission.BULK_IMPORT, false); } - + public boolean canCompact(TCredentials c, String tableId) throws ThriftSecurityException { authenticate(c); return hasSystemPermission(c, SystemPermission.ALTER_TABLE, false) || hasTablePermission(c, tableId, TablePermission.ALTER_TABLE, false) || hasTablePermission(c, tableId, TablePermission.WRITE, false); } - + public boolean canChangeAuthorizations(TCredentials c, String user) throws ThriftSecurityException { authenticate(c); return hasSystemPermission(c, SystemPermission.ALTER_USER, false); } - + public boolean canChangePassword(TCredentials c, String user) throws ThriftSecurityException { authenticate(c); return c.getPrincipal().equals(user) || hasSystemPermission(c, SystemPermission.ALTER_USER, false); } - + public boolean canCreateUser(TCredentials c, String user) throws ThriftSecurityException { authenticate(c); return hasSystemPermission(c, SystemPermission.CREATE_USER, false); } - + public boolean canDropUser(TCredentials c, String user) throws ThriftSecurityException { authenticate(c); if (user.equals(getRootUsername())) throw new ThriftSecurityException(c.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED); return hasSystemPermission(c, SystemPermission.DROP_USER, false); } - + public boolean canGrantSystem(TCredentials c, String user, SystemPermission sysPerm) throws ThriftSecurityException { authenticate(c); // can't grant GRANT @@ -444,36 +459,36 @@ public class SecurityOperation { throw new ThriftSecurityException(c.getPrincipal(), SecurityErrorCode.GRANT_INVALID); return hasSystemPermission(c, SystemPermission.GRANT, false); } - + public boolean canGrantTable(TCredentials c, String user, String table) throws ThriftSecurityException { authenticate(c); return hasSystemPermission(c, SystemPermission.ALTER_TABLE, false) || hasTablePermission(c, table, TablePermission.GRANT, false); } - + public boolean canRevokeSystem(TCredentials c, String user, SystemPermission sysPerm) throws ThriftSecurityException { authenticate(c); // can't modify root user if (user.equals(getRootUsername())) throw new ThriftSecurityException(c.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED); - + // can't revoke GRANT if (sysPerm.equals(SystemPermission.GRANT)) throw new ThriftSecurityException(c.getPrincipal(), SecurityErrorCode.GRANT_INVALID); - + return hasSystemPermission(c, SystemPermission.GRANT, false); } - + public boolean canRevokeTable(TCredentials c, String user, String table) throws ThriftSecurityException { authenticate(c); return hasSystemPermission(c, SystemPermission.ALTER_TABLE, false) || hasTablePermission(c, table, TablePermission.GRANT, false); } - + public void changeAuthorizations(TCredentials credentials, String user, Authorizations authorizations) throws ThriftSecurityException { if (!canChangeAuthorizations(credentials, user)) throw new ThriftSecurityException(credentials.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED); - + targetUserExists(user); - + try { authorizor.changeAuthorizations(user, authorizations); log.info("Changed authorizations for user " + user + " at the request of user " + credentials.getPrincipal()); @@ -481,7 +496,7 @@ public class SecurityOperation { throw ase.asThriftException(); } } - + public void changePassword(TCredentials credentials, Credentials toChange) throws ThriftSecurityException { if (!canChangePassword(credentials, toChange.getPrincipal())) throw new ThriftSecurityException(credentials.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED); @@ -493,7 +508,7 @@ public class SecurityOperation { throw e.asThriftException(); } } - + public void createUser(TCredentials credentials, Credentials newUser, Authorizations authorizations) throws ThriftSecurityException { if (!canCreateUser(credentials, newUser.getPrincipal())) throw new ThriftSecurityException(credentials.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED); @@ -509,7 +524,7 @@ public class SecurityOperation { throw ase.asThriftException(); } } - + public void dropUser(TCredentials credentials, String user) throws ThriftSecurityException { if (!canDropUser(credentials, user)) throw new ThriftSecurityException(credentials.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED); @@ -522,13 +537,13 @@ public class SecurityOperation { throw e.asThriftException(); } } - + public void grantSystemPermission(TCredentials credentials, String user, SystemPermission permissionById) throws ThriftSecurityException { if (!canGrantSystem(credentials, user, permissionById)) throw new ThriftSecurityException(credentials.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED); - + targetUserExists(user); - + try { permHandle.grantSystemPermission(user, permissionById); log.info("Granted system permission " + permissionById + " for user " + user + " at the request of user " + credentials.getPrincipal()); @@ -536,13 +551,13 @@ public class SecurityOperation { throw e.asThriftException(); } } - + public void grantTablePermission(TCredentials c, String user, String tableId, TablePermission permission) throws ThriftSecurityException { if (!canGrantTable(c, user, tableId)) throw new ThriftSecurityException(c.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED); - + targetUserExists(user); - + try { permHandle.grantTablePermission(user, tableId, permission); log.info("Granted table permission " + permission + " for user " + user + " on the table " + tableId + " at the request of user " + c.getPrincipal()); @@ -552,51 +567,51 @@ public class SecurityOperation { throw new ThriftSecurityException(c.getPrincipal(), SecurityErrorCode.TABLE_DOESNT_EXIST); } } - + public void revokeSystemPermission(TCredentials credentials, String user, SystemPermission permission) throws ThriftSecurityException { if (!canRevokeSystem(credentials, user, permission)) throw new ThriftSecurityException(credentials.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED); - + targetUserExists(user); - + try { permHandle.revokeSystemPermission(user, permission); log.info("Revoked system permission " + permission + " for user " + user + " at the request of user " + credentials.getPrincipal()); - + } catch (AccumuloSecurityException e) { throw e.asThriftException(); } } - + public void revokeTablePermission(TCredentials c, String user, String tableId, TablePermission permission) throws ThriftSecurityException { if (!canRevokeTable(c, user, tableId)) throw new ThriftSecurityException(c.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED); - + targetUserExists(user); - + try { permHandle.revokeTablePermission(user, tableId, permission); log.info("Revoked table permission " + permission + " for user " + user + " on the table " + tableId + " at the request of user " + c.getPrincipal()); - + } catch (AccumuloSecurityException e) { throw e.asThriftException(); } catch (TableNotFoundException e) { throw new ThriftSecurityException(c.getPrincipal(), SecurityErrorCode.TABLE_DOESNT_EXIST); } } - + public boolean hasSystemPermission(TCredentials credentials, String user, SystemPermission permissionById) throws ThriftSecurityException { if (!canAskAboutOtherUsers(credentials, user)) throw new ThriftSecurityException(credentials.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED); return _hasSystemPermission(user, permissionById, false); } - + public boolean hasTablePermission(TCredentials credentials, String user, String tableId, TablePermission permissionById) throws ThriftSecurityException { if (!canAskAboutOtherUsers(credentials, user)) throw new ThriftSecurityException(credentials.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED); return _hasTablePermission(user, tableId, permissionById, false); } - + public Set<String> listUsers(TCredentials credentials) throws ThriftSecurityException { authenticate(credentials); try { @@ -605,7 +620,7 @@ public class SecurityOperation { throw e.asThriftException(); } } - + public void deleteTable(TCredentials credentials, String tableId) throws ThriftSecurityException { if (!canDeleteTable(credentials, tableId)) throw new ThriftSecurityException(credentials.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED); @@ -618,12 +633,12 @@ public class SecurityOperation { throw new ThriftSecurityException(credentials.getPrincipal(), SecurityErrorCode.TABLE_DOESNT_EXIST); } } - + public boolean canExport(TCredentials credentials, String tableId, String tableName, String exportDir) throws ThriftSecurityException { authenticate(credentials); return hasTablePermission(credentials, tableId, TablePermission.READ, false); } - + public boolean canImport(TCredentials credentials, String tableName, String importDir) throws ThriftSecurityException { authenticate(credentials); return hasSystemPermission(credentials, SystemPermission.CREATE_TABLE, false); http://git-wip-us.apache.org/repos/asf/accumulo/blob/9a2041d5/server/src/main/java/org/apache/accumulo/server/security/handler/Authorizor.java ---------------------------------------------------------------------- diff --git a/server/src/main/java/org/apache/accumulo/server/security/handler/Authorizor.java b/server/src/main/java/org/apache/accumulo/server/security/handler/Authorizor.java index ab9beec..569d893 100644 --- a/server/src/main/java/org/apache/accumulo/server/security/handler/Authorizor.java +++ b/server/src/main/java/org/apache/accumulo/server/security/handler/Authorizor.java @@ -16,6 +16,9 @@ */ package org.apache.accumulo.server.security.handler; +import java.nio.ByteBuffer; +import java.util.List; + import org.apache.accumulo.core.client.AccumuloSecurityException; import org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException; import org.apache.accumulo.core.security.Authorizations; @@ -51,6 +54,11 @@ public interface Authorizor { * Used to get the authorizations for the user */ public Authorizations getCachedUserAuthorizations(String user) throws AccumuloSecurityException; + + /** + * Used to check if a user has valid auths. + */ + public boolean isValidAuthorizations(String user, List<ByteBuffer> list) throws AccumuloSecurityException; /** * Initializes a new user http://git-wip-us.apache.org/repos/asf/accumulo/blob/9a2041d5/server/src/main/java/org/apache/accumulo/server/security/handler/ZKAuthorizor.java ---------------------------------------------------------------------- diff --git a/server/src/main/java/org/apache/accumulo/server/security/handler/ZKAuthorizor.java b/server/src/main/java/org/apache/accumulo/server/security/handler/ZKAuthorizor.java index 6fe0115..71274cc 100644 --- a/server/src/main/java/org/apache/accumulo/server/security/handler/ZKAuthorizor.java +++ b/server/src/main/java/org/apache/accumulo/server/security/handler/ZKAuthorizor.java @@ -16,8 +16,11 @@ */ package org.apache.accumulo.server.security.handler; +import java.nio.ByteBuffer; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeSet; @@ -154,4 +157,13 @@ public class ZKAuthorizor implements Authorizor { } } + @Override + public boolean isValidAuthorizations(String user, List<ByteBuffer> auths) throws AccumuloSecurityException { + Collection<ByteBuffer> userauths = getCachedUserAuthorizations(user).getAuthorizationsBB(); + for (ByteBuffer auth : auths) + if (!userauths.contains(auth)) + return false; + return true; + } + }
