Uploaded image for project: 'Accumulo'
  1. Accumulo
  2. ACCUMULO-4140

SecurityOperation checks for root usernames fail when using Kerberos

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: Blocker
    • Resolution: Fixed
    • Affects Version/s: 1.7.0
    • Fix Version/s: 1.7.1, 1.8.0
    • Component/s: core
    • Labels:
      None

      Description

      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, root@EXAMPLE.COM), 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:

        "Accumulo" should "revoke app2's attempt to modify the root user" in {
          val root = UserGroupInformation.loginUserFromKeytabAndReturnUGI("root@EXAMPLE.COM", 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")
        }
      

      Output:

      - should revoke app2's attempt to modify the root user *** FAILED ***
        org.apache.accumulo.core.client.AccumuloSecurityException: Error PERMISSION_DENIED for user root@EXAMPLE.COM 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)
        ...
      

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

        Attachments

          Activity

            People

            • Assignee:
              bills William Slacum
              Reporter:
              bills William Slacum
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Time Tracking

                Estimated:
                Original Estimate - Not Specified
                Not Specified
                Remaining:
                Remaining Estimate - 0h
                0h
                Logged:
                Time Spent - 20m
                20m