William Slacum created ACCUMULO-4140:
----------------------------------------

             Summary: SecurityOperation checks for root usernames fail when 
using Kerberos
                 Key: ACCUMULO-4140
                 URL: https://issues.apache.org/jira/browse/ACCUMULO-4140
             Project: Accumulo
          Issue Type: Bug
          Components: core
    Affects Versions: 1.7.0
            Reporter: William Slacum
            Assignee: William Slacum
            Priority: Blocker
             Fix For: 1.7.1


I'm currently extending the {{KerberosAuthenticator}}, since 
{{SecurityOperation}} depends on it for a few checks (see uses of 
{{SecurityOperation#isKerberos}}). I relied on 
{{KerberosAuthenticator#initializeSecurity}} to create the root user's 
ZooKeeper entry for me. When the KerberosAuthenticator creates principals, it 
base64 encodes them. This causes the root entry under 
{{/accumulo/instance/users}} to also be base64 encoded.

In a few spots, {{SecurityOperation}} will try to short circuit things by 
checking if the user has the root user name. This will fail because the 
principal will be in plain-form (ie, {{[email protected]}}), and the data from 
ZooKeeper is base-64 encoded.

This opens up a security hole where the root user can have its permissions 
altered. I had a small test where I created a new user, gave it 
{{SystemPermission.GRANT}}, then revoked the root user's ability to create a 
table (this is explicitly disallowed in {{SecurityOperation#canRevokeSystem}}).

Test:

{code}
  "Accumulo" should "revoke app2's attempt to modify the root user" in {
    val root = 
UserGroupInformation.loginUserFromKeytabAndReturnUGI("[email protected]", 
kdc.getRootUser.getKeytab.getAbsolutePath)
    val con = accumulo.getConnector(root.getUserName, new KerberosToken)
    con.securityOperations.grantSystemPermission(app1.getUserName, 
SystemPermission.GRANT)
    doAs(app1, () => {
      val con = accumulo.getConnector(app1.getUserName, new KerberosToken)
      con.securityOperations.revokeSystemPermission(root.getUserName, 
SystemPermission.CREATE_TABLE)
    })
    // this will now throw an error
    con.tableOperations.create("hopefully_I_can_create_ this")
  }
{code}

Output:
{noformat}
- should revoke app2's attempt to modify the root user *** FAILED ***
  org.apache.accumulo.core.client.AccumuloSecurityException: Error 
PERMISSION_DENIED for user [email protected] on table 
hopefully_I_can_create_this(?) - User does not have permission to perform this 
action
  at 
org.apache.accumulo.core.client.impl.TableOperationsImpl.doFateOperation(TableOperationsImpl.java:285)
  at 
org.apache.accumulo.core.client.impl.TableOperationsImpl.doFateOperation(TableOperationsImpl.java:261)
  at 
org.apache.accumulo.core.client.impl.TableOperationsImpl.doTableFateOperation(TableOperationsImpl.java:1427)
  at 
org.apache.accumulo.core.client.impl.TableOperationsImpl.create(TableOperationsImpl.java:188)
  at 
org.apache.accumulo.core.client.impl.TableOperationsImpl.create(TableOperationsImpl.java:155)
  at KerbSpec$$anonfun$8.apply$mcV$sp(ServerTest.scala:131)
  at KerbSpec$$anonfun$8.apply(ServerTest.scala:122)
  at KerbSpec$$anonfun$8.apply(ServerTest.scala:122)
  at 
org.scalatest.Transformer$$anonfun$apply$1.apply$mcV$sp(Transformer.scala:22)
  at org.scalatest.OutcomeOf$class.outcomeOf(OutcomeOf.scala:85)
  ...
  Cause: org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException:
  at 
org.apache.accumulo.core.master.thrift.FateService$executeFateOperation_result$executeFateOperation_resultStandardScheme.read(FateService.java:3129)
  at 
org.apache.accumulo.core.master.thrift.FateService$executeFateOperation_result$executeFateOperation_resultStandardScheme.read(FateService.java:3115)
  at 
org.apache.accumulo.core.master.thrift.FateService$executeFateOperation_result.read(FateService.java:3057)
  at org.apache.thrift.TServiceClient.receiveBase(TServiceClient.java:78)
  at 
org.apache.accumulo.core.master.thrift.FateService$Client.recv_executeFateOperation(FateService.java:146)
  at 
org.apache.accumulo.core.master.thrift.FateService$Client.executeFateOperation(FateService.java:127)
  at 
org.apache.accumulo.core.client.impl.TableOperationsImpl.executeFateOperation(TableOperationsImpl.java:217)
  at 
org.apache.accumulo.core.client.impl.TableOperationsImpl.doFateOperation(TableOperationsImpl.java:270)
  at 
org.apache.accumulo.core.client.impl.TableOperationsImpl.doFateOperation(TableOperationsImpl.java:261)
  at 
org.apache.accumulo.core.client.impl.TableOperationsImpl.doTableFateOperation(TableOperationsImpl.java:1427)
  ...
{noformat}

I'm reasonably certain the that the fix is to just have the 
{{KerberosAuthenticator}} not base64 encode the root principal when 
{{initializeSecurity}} is called.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to