@Override public Status run() { KerberosToken token; try { // Do *not* replace the current user token = new KerberosToken(principal, keytab); } catch (IOException e) { log.error("Failed to create KerberosToken", e); return status; } ClientContext peerContext = getContextForPeer(localConf, target, principal, token); return _replicate(p, status, target, helper, localConf, peerContext, accumuloUgi); } });
/** * Creates a token using the provided principal and the currently logged-in user via * {@link UserGroupInformation}. * * This method expects the current user (as defined by * {@link UserGroupInformation#getCurrentUser()} to be authenticated via Kerberos or as a Proxy * (on top of another user). An {@link IllegalArgumentException} will be thrown for all other * cases. * * @param principal * The user that is logged in * @throws IllegalArgumentException * If the current user is not authentication via Kerberos or Proxy methods. * @see UserGroupInformation#getCurrentUser() * @see UserGroupInformation#getAuthenticationMethod() */ public KerberosToken(String principal) throws IOException { this.principal = requireNonNull(principal); validateAuthMethod(UserGroupInformation.getCurrentUser().getAuthenticationMethod()); }
@Override public Integer call() { try { ClientConfiguration clientConf = cluster.getClientConfig(); // Invocation is different for SASL. We're only logged in via this processes memory (not // via some credentials cache on disk) // Need to pass along the keytab because of that. if (clientConf.hasSasl()) { String principal = getAdminPrincipal(); AuthenticationToken token = getAdminToken(); assertTrue("Expected KerberosToken, but was " + token.getClass(), token instanceof KerberosToken); KerberosToken kt = (KerberosToken) token; assertNotNull("Expected keytab in token", kt.getKeytab()); return control.exec(TestMultiTableIngest.class, args("--count", Integer.toString(ROWS), "-i", instance, "-z", keepers, "--tablePrefix", prefix, "--keytab", kt.getKeytab().getAbsolutePath(), "-u", principal)); } return control.exec(TestMultiTableIngest.class, args("--count", Integer.toString(ROWS), "-u", getAdminPrincipal(), "-i", instance, "-z", keepers, "-p", new String(((PasswordToken) getAdminToken()).getPassword(), UTF_8), "--tablePrefix", prefix)); } catch (IOException e) { log.error("Error running MultiTableIngest", e); return -1; } } });
public String getPrincipal() throws AccumuloSecurityException { if (null == principal) { AuthenticationToken token = getToken(); if (null == token) { throw new AccumuloSecurityException("No principal or authentication token was provided", SecurityErrorCode.BAD_CREDENTIALS); } // In MapReduce, if we create a DelegationToken, the principal is updated from the // KerberosToken // used to obtain the DelegationToken. if (null != principal) { return principal; } // Try to extract the principal automatically from Kerberos if (token instanceof KerberosToken) { principal = ((KerberosToken) token).getPrincipal(); } else { principal = System.getProperty("user.name"); } } return principal; }
@Override public Integer call() { try { ClientConfiguration clientConf = cluster.getClientConfig(); // Invocation is different for SASL. We're only logged in via this processes memory (not // via some credentials cache on disk) // Need to pass along the keytab because of that. if (clientConf.hasSasl()) { String principal = getAdminPrincipal(); AuthenticationToken token = getAdminToken(); assertTrue("Expected KerberosToken, but was " + token.getClass(), token instanceof KerberosToken); KerberosToken kt = (KerberosToken) token; assertNotNull("Expected keytab in token", kt.getKeytab()); return control.exec(TestMultiTableIngest.class, args("--count", Integer.toString(ROWS), "--readonly", "-i", instance, "-z", keepers, "--tablePrefix", prefix, "--keytab", kt.getKeytab().getAbsolutePath(), "-u", principal)); } return control.exec(TestMultiTableIngest.class, args("--count", Integer.toString(ROWS), "--readonly", "-u", getAdminPrincipal(), "-i", instance, "-z", keepers, "-p", new String(((PasswordToken) getAdminToken()).getPassword(), UTF_8), "--tablePrefix", prefix)); } catch (IOException e) { log.error("Error running MultiTableIngest", e); return -1; } } });
@SuppressFBWarnings(value = "PATH_TRAVERSAL_IN", justification = "code runs in same security context as user who providing the token file") public static AuthenticationToken getAuthenticationToken(Properties properties) { String authType = ClientProperty.AUTH_TYPE.getValue(properties); String token = ClientProperty.AUTH_TOKEN.getValue(properties); switch (authType) { case "password": return new PasswordToken(token); case "PasswordToken": return decodeToken(PasswordToken.class.getName(), token); case "kerberos": try { String principal = ClientProperty.AUTH_PRINCIPAL.getValue(properties); return new KerberosToken(principal, new File(token)); } catch (IOException e) { throw new IllegalArgumentException(e); } case "KerberosToken": return decodeToken(KerberosToken.class.getName(), token); case "CredentialProviderToken": return decodeToken(CredentialProviderToken.class.getName(), token); case "DelegationToken": return decodeToken(DelegationToken.class.getName(), token); default: return decodeToken(authType, token); } }
/** * Creates a token using the provided principal and the currently logged-in user via * {@link UserGroupInformation}. * * This method expects the current user (as defined by * {@link UserGroupInformation#getCurrentUser()} to be authenticated via Kerberos or as a Proxy * (on top of another user). An {@link IllegalArgumentException} will be thrown for all other * cases. * * @param principal * The user that is logged in * @throws IllegalArgumentException * If the current user is not authentication via Kerberos or Proxy methods. * @see UserGroupInformation#getCurrentUser() * @see UserGroupInformation#getAuthenticationMethod() */ public KerberosToken(String principal) throws IOException { this.principal = requireNonNull(principal); validateAuthMethod(UserGroupInformation.getCurrentUser().getAuthenticationMethod()); }
@Override public void createLocalUser(TInfo tinfo, TCredentials credentials, String principal, ByteBuffer password) throws ThriftSecurityException { AuthenticationToken token; if (context.getSaslParams() != null) { try { token = new KerberosToken(); } catch (IOException e) { log.warn("Failed to create KerberosToken"); throw new ThriftSecurityException(e.getMessage(), SecurityErrorCode.DEFAULT_SECURITY_ERROR); } } else { token = new PasswordToken(password); } Credentials newUser = new Credentials(principal, token); security.createUser(credentials, newUser, new Authorizations()); }
client = traceUgi.doAs((PrivilegedExceptionAction<AccumuloClient>) () -> { AuthenticationToken token = new KerberosToken(); return Accumulo.newClient().from(props).as(principal, token).build(); });
@Override public Scanner run() throws Exception { // Make the KerberosToken inside the doAs AuthenticationToken token = at; if (null == token) { token = new KerberosToken(); } return getScanner(table, principal, token, sb); }
/** * Instantiate a KerberosToken in a backwards compatible manner. * @param username Kerberos principal */ KerberosToken getKerberosToken(String username) { try { return new KerberosToken(username); } catch (IOException e) { throw new IllegalArgumentException("Failed to instantiate KerberosToken.", e); } }
/** * Instantiate a KerberosToken in a backwards compatible manner. * @param username Kerberos principal * @param keytab Keytab on local filesystem */ KerberosToken getKerberosToken(String username, String keytab) { try { return new KerberosToken(username, new File(keytab), true); } catch (IOException e) { throw new IllegalArgumentException("Failed to instantiate KerberosToken.", e); } } }
@Override public Status run() { KerberosToken token; try { // Do *not* replace the current user token = new KerberosToken(principal, keytab); } catch (IOException e) { log.error("Failed to create KerberosToken", e); return status; } ClientContext peerContext = getContextForPeer(localConf, target, principal, token); return _replicate(p, status, target, helper, localConf, peerContext, accumuloUgi); } });
public AuthenticationToken getAuthenticationToken() throws Exception { if (null == authenticationToken) { final ClientConfiguration clientConf = getClientConfiguration(); // Automatically use a KerberosToken if the client conf is configured for SASL final boolean saslEnabled = Boolean .parseBoolean(clientConf.get(ClientProperty.INSTANCE_RPC_SASL_ENABLED)); if (saslEnabled) { authenticationToken = new KerberosToken(); } } return authenticationToken; }
/** * Computes the appropriate {@link AuthenticationToken} for the user represented by this object. * May not yet be created in Accumulo. * * @return the correct {@link AuthenticationToken} to use with Accumulo for this user * @throws IOException * if performing necessary login failed */ public AuthenticationToken getToken() throws IOException { if (null != password) { return new PasswordToken(password); } else if (null != keytab) { UserGroupInformation.loginUserFromKeytab(principal, keytab.getAbsolutePath()); return new KerberosToken(); } throw new IllegalStateException("One of password and keytab must be non-null"); }
/** * Gets an authentication token based on the configured password. * * @return authentication token */ public AuthenticationToken getToken() { String password = getPassword(); if (null != password) { return new PasswordToken(getPassword()); } String keytab = getKeytab(); if (null != keytab) { File keytabFile = new File(keytab); if (!keytabFile.exists() || !keytabFile.isFile()) { throw new IllegalArgumentException("Provided keytab is not a normal file: " + keytab); } try { UserGroupInformation.loginUserFromKeytab(getUserName(), keytabFile.getAbsolutePath()); return new KerberosToken(); } catch (IOException e) { throw new RuntimeException("Failed to login", e); } } throw new IllegalArgumentException("Must provide password or keytab in configuration"); }
@Test public void testAdminUser() throws Exception { // Login as the client (provided to `accumulo init` as the "root" user) UserGroupInformation ugi = UserGroupInformation.loginUserFromKeytabAndReturnUGI( rootUser.getPrincipal(), rootUser.getKeytab().getAbsolutePath()); ugi.doAs(new PrivilegedExceptionAction<Void>() { @Override public Void run() throws Exception { final Connector conn = mac.getConnector(rootUser.getPrincipal(), new KerberosToken()); // The "root" user should have all system permissions for (SystemPermission perm : SystemPermission.values()) { assertTrue("Expected user to have permission: " + perm, conn.securityOperations().hasSystemPermission(conn.whoami(), perm)); } // and the ability to modify the root and metadata tables for (String table : Arrays.asList(RootTable.NAME, MetadataTable.NAME)) { assertTrue(conn.securityOperations().hasTablePermission(conn.whoami(), table, TablePermission.ALTER_TABLE)); } return null; } }); }
@Override public Void run() throws Exception { // Indirectly creates this user when we use it Connector conn = mac.getConnector(qualifiedUser1, new KerberosToken()); log.info("Created connector as {}", qualifiedUser1); // The new user should have no system permissions for (SystemPermission perm : SystemPermission.values()) { assertFalse(conn.securityOperations().hasSystemPermission(qualifiedUser1, perm)); } return null; }
@Override public Void run() throws Exception { // Indirectly creates this user when we use it Connector conn = mac.getConnector(qualifiedUser1, new KerberosToken()); log.info("Created connector as {}", qualifiedUser1); // The new user should have no system permissions for (SystemPermission perm : SystemPermission.values()) { assertFalse(conn.securityOperations().hasSystemPermission(qualifiedUser1, perm)); } return null; } });
@Override public Void run() throws Exception { Connector conn = mac.getConnector(rootUser.getPrincipal(), new KerberosToken()); conn.securityOperations().grantSystemPermission(qualifiedUser1, SystemPermission.CREATE_TABLE); return null; } });