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();
}
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();
}
}
}
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();
}
}
}
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");
}
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);
}
Aggregations