Search in sources :

Example 1 with Client

use of org.apache.accumulo.proxy.thrift.AccumuloProxy.Client in project accumulo by apache.

the class KerberosProxyIT method testProxyClient.

@Test
public void testProxyClient() throws Exception {
    ClusterUser rootUser = kdc.getRootUser();
    UserGroupInformation ugi = UserGroupInformation.loginUserFromKeytabAndReturnUGI(rootUser.getPrincipal(), rootUser.getKeytab().getAbsolutePath());
    TSocket socket = new TSocket(hostname, proxyPort);
    log.info("Connecting to proxy with server primary '{}' running on {}", proxyPrimary, hostname);
    TSaslClientTransport transport = new TSaslClientTransport("GSSAPI", null, proxyPrimary, hostname, Collections.singletonMap("javax.security.sasl.qop", "auth"), null, socket);
    final UGIAssumingTransport ugiTransport = new UGIAssumingTransport(transport, ugi);
    // UGI transport will perform the doAs for us
    ugiTransport.open();
    AccumuloProxy.Client.Factory factory = new AccumuloProxy.Client.Factory();
    Client client = factory.getClient(new TCompactProtocol(ugiTransport), new TCompactProtocol(ugiTransport));
    // Will fail if the proxy can impersonate the client
    ByteBuffer login = client.login(rootUser.getPrincipal(), Collections.<String, String>emptyMap());
    // For all of the below actions, the proxy user doesn't have permission to do any of them, but the client user does.
    // The fact that any of them actually run tells us that impersonation is working.
    // Create a table
    String table = "table";
    if (!client.tableExists(login, table)) {
        client.createTable(login, table, true, TimeType.MILLIS);
    }
    // Write two records to the table
    String writer = client.createWriter(login, table, new WriterOptions());
    Map<ByteBuffer, List<ColumnUpdate>> updates = new HashMap<>();
    ColumnUpdate update = new ColumnUpdate(ByteBuffer.wrap("cf1".getBytes(UTF_8)), ByteBuffer.wrap("cq1".getBytes(UTF_8)));
    update.setValue(ByteBuffer.wrap("value1".getBytes(UTF_8)));
    updates.put(ByteBuffer.wrap("row1".getBytes(UTF_8)), Collections.singletonList(update));
    update = new ColumnUpdate(ByteBuffer.wrap("cf2".getBytes(UTF_8)), ByteBuffer.wrap("cq2".getBytes(UTF_8)));
    update.setValue(ByteBuffer.wrap("value2".getBytes(UTF_8)));
    updates.put(ByteBuffer.wrap("row2".getBytes(UTF_8)), Collections.singletonList(update));
    client.update(writer, updates);
    // Flush and close the writer
    client.flush(writer);
    client.closeWriter(writer);
    // Open a scanner to the table
    String scanner = client.createScanner(login, table, new ScanOptions());
    ScanResult results = client.nextK(scanner, 10);
    assertEquals(2, results.getResults().size());
    // Check the first key-value
    KeyValue kv = results.getResults().get(0);
    Key k = kv.key;
    ByteBuffer v = kv.value;
    assertEquals(ByteBuffer.wrap("row1".getBytes(UTF_8)), k.row);
    assertEquals(ByteBuffer.wrap("cf1".getBytes(UTF_8)), k.colFamily);
    assertEquals(ByteBuffer.wrap("cq1".getBytes(UTF_8)), k.colQualifier);
    assertEquals(ByteBuffer.wrap(new byte[0]), k.colVisibility);
    assertEquals(ByteBuffer.wrap("value1".getBytes(UTF_8)), v);
    // And then the second
    kv = results.getResults().get(1);
    k = kv.key;
    v = kv.value;
    assertEquals(ByteBuffer.wrap("row2".getBytes(UTF_8)), k.row);
    assertEquals(ByteBuffer.wrap("cf2".getBytes(UTF_8)), k.colFamily);
    assertEquals(ByteBuffer.wrap("cq2".getBytes(UTF_8)), k.colQualifier);
    assertEquals(ByteBuffer.wrap(new byte[0]), k.colVisibility);
    assertEquals(ByteBuffer.wrap("value2".getBytes(UTF_8)), v);
    // Close the scanner
    client.closeScanner(scanner);
    ugiTransport.close();
}
Also used : AccumuloProxy(org.apache.accumulo.proxy.thrift.AccumuloProxy) ScanResult(org.apache.accumulo.proxy.thrift.ScanResult) ColumnUpdate(org.apache.accumulo.proxy.thrift.ColumnUpdate) KeyValue(org.apache.accumulo.proxy.thrift.KeyValue) HashMap(java.util.HashMap) LoggerFactory(org.slf4j.LoggerFactory) TSaslClientTransport(org.apache.thrift.transport.TSaslClientTransport) TCompactProtocol(org.apache.thrift.protocol.TCompactProtocol) ByteBuffer(java.nio.ByteBuffer) UGIAssumingTransport(org.apache.accumulo.core.rpc.UGIAssumingTransport) WriterOptions(org.apache.accumulo.proxy.thrift.WriterOptions) ClusterUser(org.apache.accumulo.cluster.ClusterUser) List(java.util.List) ScanOptions(org.apache.accumulo.proxy.thrift.ScanOptions) Client(org.apache.accumulo.proxy.thrift.AccumuloProxy.Client) Key(org.apache.accumulo.proxy.thrift.Key) UserGroupInformation(org.apache.hadoop.security.UserGroupInformation) TSocket(org.apache.thrift.transport.TSocket) Test(org.junit.Test)

Example 2 with Client

use of org.apache.accumulo.proxy.thrift.AccumuloProxy.Client in project accumulo by apache.

the class KerberosProxyIT method testDisallowedClientForImpersonation.

@Test
public void testDisallowedClientForImpersonation() throws Exception {
    String user = testName.getMethodName();
    File keytab = new File(kdc.getKeytabDir(), user + ".keytab");
    kdc.createPrincipal(keytab, user);
    // Login as the new user
    UserGroupInformation ugi = UserGroupInformation.loginUserFromKeytabAndReturnUGI(user, keytab.getAbsolutePath());
    log.info("Logged in as {}", ugi);
    // Expect an AccumuloSecurityException
    thrown.expect(AccumuloSecurityException.class);
    // Error msg would look like:
    // 
    // org.apache.accumulo.core.client.AccumuloSecurityException: Error BAD_CREDENTIALS for user Principal in credentials object should match kerberos
    // principal.
    // Expected 'proxy/hw10447.local@EXAMPLE.COM' but was 'testDisallowedClientForImpersonation@EXAMPLE.COM' - Username or Password is Invalid)
    thrown.expect(new ThriftExceptionMatchesPattern(".*Error BAD_CREDENTIALS.*"));
    thrown.expect(new ThriftExceptionMatchesPattern(".*Expected '" + proxyPrincipal + "' but was '" + kdc.qualifyUser(user) + "'.*"));
    TSocket socket = new TSocket(hostname, proxyPort);
    log.info("Connecting to proxy with server primary '{}' running on {}", proxyPrimary, hostname);
    // Should fail to open the tran
    TSaslClientTransport transport = new TSaslClientTransport("GSSAPI", null, proxyPrimary, hostname, Collections.singletonMap("javax.security.sasl.qop", "auth"), null, socket);
    final UGIAssumingTransport ugiTransport = new UGIAssumingTransport(transport, ugi);
    // UGI transport will perform the doAs for us
    ugiTransport.open();
    AccumuloProxy.Client.Factory factory = new AccumuloProxy.Client.Factory();
    Client client = factory.getClient(new TCompactProtocol(ugiTransport), new TCompactProtocol(ugiTransport));
    // Will fail because the proxy can't impersonate this user (per the site configuration)
    try {
        client.login(kdc.qualifyUser(user), Collections.<String, String>emptyMap());
    } finally {
        if (null != ugiTransport) {
            ugiTransport.close();
        }
    }
}
Also used : UGIAssumingTransport(org.apache.accumulo.core.rpc.UGIAssumingTransport) AccumuloProxy(org.apache.accumulo.proxy.thrift.AccumuloProxy) LoggerFactory(org.slf4j.LoggerFactory) TSaslClientTransport(org.apache.thrift.transport.TSaslClientTransport) Client(org.apache.accumulo.proxy.thrift.AccumuloProxy.Client) TCompactProtocol(org.apache.thrift.protocol.TCompactProtocol) File(java.io.File) UserGroupInformation(org.apache.hadoop.security.UserGroupInformation) TSocket(org.apache.thrift.transport.TSocket) Test(org.junit.Test)

Example 3 with Client

use of org.apache.accumulo.proxy.thrift.AccumuloProxy.Client in project accumulo by apache.

the class KerberosProxyIT method testMismatchPrincipals.

@Test
public void testMismatchPrincipals() throws Exception {
    ClusterUser rootUser = kdc.getRootUser();
    // Should get an AccumuloSecurityException and the given message
    thrown.expect(AccumuloSecurityException.class);
    thrown.expect(new ThriftExceptionMatchesPattern(ProxyServer.RPC_ACCUMULO_PRINCIPAL_MISMATCH_MSG));
    // Make a new user
    String user = testName.getMethodName();
    File keytab = new File(kdc.getKeytabDir(), user + ".keytab");
    kdc.createPrincipal(keytab, user);
    // Login as the new user
    UserGroupInformation ugi = UserGroupInformation.loginUserFromKeytabAndReturnUGI(user, keytab.getAbsolutePath());
    log.info("Logged in as {}", ugi);
    TSocket socket = new TSocket(hostname, proxyPort);
    log.info("Connecting to proxy with server primary '{}' running on {}", proxyPrimary, hostname);
    // Should fail to open the tran
    TSaslClientTransport transport = new TSaslClientTransport("GSSAPI", null, proxyPrimary, hostname, Collections.singletonMap("javax.security.sasl.qop", "auth"), null, socket);
    final UGIAssumingTransport ugiTransport = new UGIAssumingTransport(transport, ugi);
    // UGI transport will perform the doAs for us
    ugiTransport.open();
    AccumuloProxy.Client.Factory factory = new AccumuloProxy.Client.Factory();
    Client client = factory.getClient(new TCompactProtocol(ugiTransport), new TCompactProtocol(ugiTransport));
    // Accumulo should let this through -- we need to rely on the proxy to dump me before talking to accumulo
    try {
        client.login(rootUser.getPrincipal(), Collections.<String, String>emptyMap());
    } finally {
        if (null != ugiTransport) {
            ugiTransport.close();
        }
    }
}
Also used : AccumuloProxy(org.apache.accumulo.proxy.thrift.AccumuloProxy) LoggerFactory(org.slf4j.LoggerFactory) TSaslClientTransport(org.apache.thrift.transport.TSaslClientTransport) TCompactProtocol(org.apache.thrift.protocol.TCompactProtocol) UGIAssumingTransport(org.apache.accumulo.core.rpc.UGIAssumingTransport) ClusterUser(org.apache.accumulo.cluster.ClusterUser) Client(org.apache.accumulo.proxy.thrift.AccumuloProxy.Client) File(java.io.File) UserGroupInformation(org.apache.hadoop.security.UserGroupInformation) TSocket(org.apache.thrift.transport.TSocket) Test(org.junit.Test)

Example 4 with Client

use of org.apache.accumulo.proxy.thrift.AccumuloProxy.Client in project accumulo by apache.

the class SimpleProxyBase method namespacePermissions.

@Test
public void namespacePermissions() throws Exception {
    String userName;
    ClusterUser otherClient = null;
    ByteBuffer password = s2bb("password");
    ByteBuffer user;
    TestProxyClient origProxyClient = null;
    Client origClient = null;
    TestProxyClient userProxyClient = null;
    Client userClient = null;
    if (isKerberosEnabled()) {
        otherClient = getKdc().getClientPrincipal(1);
        userName = otherClient.getPrincipal();
        UserGroupInformation.loginUserFromKeytab(otherClient.getPrincipal(), otherClient.getKeytab().getAbsolutePath());
        final UserGroupInformation ugi = UserGroupInformation.getCurrentUser();
        // Re-login in and make a new connection. Can't use the previous one
        userProxyClient = new TestProxyClient(hostname, proxyPort, factory, proxyPrimary, ugi);
        origProxyClient = proxyClient;
        origClient = client;
        userClient = client = userProxyClient.proxy();
        user = client.login(userName, Collections.<String, String>emptyMap());
    } else {
        userName = getUniqueNames(1)[0];
        // create a user
        client.createLocalUser(creds, userName, password);
        user = client.login(userName, s2pp(ByteBufferUtil.toString(password)));
    }
    // check permission failure
    try {
        client.createTable(user, namespaceName + ".fail", true, TimeType.MILLIS);
        fail("should not create the table");
    } catch (AccumuloSecurityException ex) {
        if (isKerberosEnabled()) {
            // Switch back to original client
            UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
            client = origClient;
        }
        assertFalse(client.listTables(creds).contains(namespaceName + ".fail"));
    }
    // grant permissions and test
    assertFalse(client.hasNamespacePermission(creds, userName, namespaceName, NamespacePermission.CREATE_TABLE));
    client.grantNamespacePermission(creds, userName, namespaceName, NamespacePermission.CREATE_TABLE);
    assertTrue(client.hasNamespacePermission(creds, userName, namespaceName, NamespacePermission.CREATE_TABLE));
    if (isKerberosEnabled()) {
        // Switch back to the extra user
        UserGroupInformation.loginUserFromKeytab(otherClient.getPrincipal(), otherClient.getKeytab().getAbsolutePath());
        client = userClient;
    }
    client.createTable(user, namespaceName + ".success", true, TimeType.MILLIS);
    if (isKerberosEnabled()) {
        // Switch back to original client
        UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
        client = origClient;
    }
    assertTrue(client.listTables(creds).contains(namespaceName + ".success"));
    // revoke permissions
    client.revokeNamespacePermission(creds, userName, namespaceName, NamespacePermission.CREATE_TABLE);
    assertFalse(client.hasNamespacePermission(creds, userName, namespaceName, NamespacePermission.CREATE_TABLE));
    try {
        if (isKerberosEnabled()) {
            // Switch back to the extra user
            UserGroupInformation.loginUserFromKeytab(otherClient.getPrincipal(), otherClient.getKeytab().getAbsolutePath());
            client = userClient;
        }
        client.createTable(user, namespaceName + ".fail", true, TimeType.MILLIS);
        fail("should not create the table");
    } catch (AccumuloSecurityException ex) {
        if (isKerberosEnabled()) {
            // Switch back to original client
            UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
            client = origClient;
        }
        assertFalse(client.listTables(creds).contains(namespaceName + ".fail"));
    }
    // delete user
    client.dropLocalUser(creds, userName);
    Set<String> users = client.listLocalUsers(creds);
    assertFalse("Should not see user after they are deleted", users.contains(userName));
    if (isKerberosEnabled()) {
        userProxyClient.close();
        proxyClient = origProxyClient;
        client = origClient;
    }
    // delete table from namespace otherwise we can't delete namespace during teardown
    client.deleteTable(creds, namespaceName + ".success");
}
Also used : ClusterUser(org.apache.accumulo.cluster.ClusterUser) AccumuloSecurityException(org.apache.accumulo.proxy.thrift.AccumuloSecurityException) Client(org.apache.accumulo.proxy.thrift.AccumuloProxy.Client) ByteBuffer(java.nio.ByteBuffer) UserGroupInformation(org.apache.hadoop.security.UserGroupInformation) Test(org.junit.Test)

Example 5 with Client

use of org.apache.accumulo.proxy.thrift.AccumuloProxy.Client in project accumulo by apache.

the class SimpleProxyBase method attachIteratorsWithScans.

@Test
public void attachIteratorsWithScans() throws Exception {
    if (client.tableExists(creds, "slow")) {
        client.deleteTable(creds, "slow");
    }
    // create a table that's very slow, so we can look for scans
    client.createTable(creds, "slow", true, TimeType.MILLIS);
    IteratorSetting setting = new IteratorSetting(100, "slow", SlowIterator.class.getName(), Collections.singletonMap("sleepTime", "250"));
    client.attachIterator(creds, "slow", setting, EnumSet.allOf(IteratorScope.class));
    // Should take 10 seconds to read every record
    for (int i = 0; i < 40; i++) {
        client.updateAndFlush(creds, "slow", mutation("row" + i, "cf", "cq", "value"));
    }
    // scan
    Thread t = new Thread() {

        @Override
        public void run() {
            String scanner;
            TestProxyClient proxyClient2 = null;
            try {
                if (isKerberosEnabled()) {
                    UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
                    proxyClient2 = new TestProxyClient(hostname, proxyPort, factory, proxyPrimary, UserGroupInformation.getCurrentUser());
                } else {
                    proxyClient2 = new TestProxyClient(hostname, proxyPort, factory);
                }
                Client client2 = proxyClient2.proxy();
                scanner = client2.createScanner(creds, "slow", null);
                client2.nextK(scanner, 10);
                client2.closeScanner(scanner);
            } catch (Exception e) {
                throw new RuntimeException(e);
            } finally {
                if (null != proxyClient2) {
                    proxyClient2.close();
                }
            }
        }
    };
    t.start();
    // look for the scan many times
    List<ActiveScan> scans = new ArrayList<>();
    for (int i = 0; i < 100 && scans.isEmpty(); i++) {
        for (String tserver : client.getTabletServers(creds)) {
            List<ActiveScan> scansForServer = client.getActiveScans(creds, tserver);
            for (ActiveScan scan : scansForServer) {
                if (clientPrincipal.equals(scan.getUser())) {
                    scans.add(scan);
                }
            }
            if (!scans.isEmpty())
                break;
            sleepUninterruptibly(100, TimeUnit.MILLISECONDS);
        }
    }
    t.join();
    assertFalse("Expected to find scans, but found none", scans.isEmpty());
    boolean found = false;
    Map<String, String> map = null;
    for (int i = 0; i < scans.size() && !found; i++) {
        ActiveScan scan = scans.get(i);
        if (clientPrincipal.equals(scan.getUser())) {
            assertTrue(ScanState.RUNNING.equals(scan.getState()) || ScanState.QUEUED.equals(scan.getState()));
            assertEquals(ScanType.SINGLE, scan.getType());
            assertEquals("slow", scan.getTable());
            map = client.tableIdMap(creds);
            assertEquals(map.get("slow"), scan.getExtent().tableId);
            assertTrue(scan.getExtent().endRow == null);
            assertTrue(scan.getExtent().prevEndRow == null);
            found = true;
        }
    }
    assertTrue("Could not find a scan against the 'slow' table", found);
}
Also used : ActiveScan(org.apache.accumulo.proxy.thrift.ActiveScan) ArrayList(java.util.ArrayList) NumericValueConstraint(org.apache.accumulo.test.constraints.NumericValueConstraint) TableNotFoundException(org.apache.accumulo.proxy.thrift.TableNotFoundException) MutationsRejectedException(org.apache.accumulo.proxy.thrift.MutationsRejectedException) NamespaceNotEmptyException(org.apache.accumulo.proxy.thrift.NamespaceNotEmptyException) AccumuloSecurityException(org.apache.accumulo.proxy.thrift.AccumuloSecurityException) TException(org.apache.thrift.TException) NamespaceExistsException(org.apache.accumulo.proxy.thrift.NamespaceExistsException) NamespaceNotFoundException(org.apache.accumulo.proxy.thrift.NamespaceNotFoundException) TApplicationException(org.apache.thrift.TApplicationException) TableExistsException(org.apache.accumulo.proxy.thrift.TableExistsException) IteratorSetting(org.apache.accumulo.proxy.thrift.IteratorSetting) IteratorScope(org.apache.accumulo.proxy.thrift.IteratorScope) Client(org.apache.accumulo.proxy.thrift.AccumuloProxy.Client) SlowIterator(org.apache.accumulo.test.functional.SlowIterator) Test(org.junit.Test)

Aggregations

Client (org.apache.accumulo.proxy.thrift.AccumuloProxy.Client)10 Test (org.junit.Test)9 UserGroupInformation (org.apache.hadoop.security.UserGroupInformation)7 ClusterUser (org.apache.accumulo.cluster.ClusterUser)6 ByteBuffer (java.nio.ByteBuffer)5 AccumuloSecurityException (org.apache.accumulo.proxy.thrift.AccumuloSecurityException)4 File (java.io.File)3 UGIAssumingTransport (org.apache.accumulo.core.rpc.UGIAssumingTransport)3 AccumuloProxy (org.apache.accumulo.proxy.thrift.AccumuloProxy)3 IteratorSetting (org.apache.accumulo.proxy.thrift.IteratorSetting)3 NumericValueConstraint (org.apache.accumulo.test.constraints.NumericValueConstraint)3 TCompactProtocol (org.apache.thrift.protocol.TCompactProtocol)3 TSaslClientTransport (org.apache.thrift.transport.TSaslClientTransport)3 TSocket (org.apache.thrift.transport.TSocket)3 LoggerFactory (org.slf4j.LoggerFactory)3 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 List (java.util.List)2 Column (org.apache.accumulo.proxy.thrift.Column)2 ColumnUpdate (org.apache.accumulo.proxy.thrift.ColumnUpdate)2