/** * Log a user in from a keytab file. Loads a user identity from a keytab file and login them in. * This new user does not affect the currently logged-in user. * * @param user the principal name to load from the keytab * @param path the path to the keytab file * @throws IOException if the keytab file can't be read */ public static synchronized UserGroupInformation loginUserFromKeytabAndReturnUGI( String user, String path) throws IOException { if (!isSecurityEnabled()) return UserGroupInformation.getCurrentUser(); String oldKeytabFile = null; String oldKeytabPrincipal = null; long start = 0; try { oldKeytabFile = keytabFile; oldKeytabPrincipal = keytabPrincipal; keytabFile = path; keytabPrincipal = user; Subject subject = new Subject(); LoginContext login = new LoginContext(HadoopConfiguration.KEYTAB_KERBEROS_CONFIG_NAME, subject); start = System.currentTimeMillis(); login.login(); metrics.loginSuccess.inc(System.currentTimeMillis() - start); UserGroupInformation newLoginUser = new UserGroupInformation(subject); newLoginUser.setLogin(login); newLoginUser.setAuthenticationMethod(AuthenticationMethod.KERBEROS); return newLoginUser; } catch (LoginException le) { if (start > 0) { metrics.loginFailure.inc(System.currentTimeMillis() - start); } throw new IOException("Login failure for " + user + " from keytab " + path, le); } finally { if (oldKeytabFile != null) keytabFile = oldKeytabFile; if (oldKeytabPrincipal != null) keytabPrincipal = oldKeytabPrincipal; } }
/** * Log a user in from a keytab file. Loads a user identity from a keytab file and logs them in. * They become the currently logged-in user. * * @param user the principal name to load from the keytab * @param path the path to the keytab file * @throws IOException if the keytab file can't be read */ public static synchronized void loginUserFromKeytab(String user, String path) throws IOException { if (!isSecurityEnabled()) { return; } keytabFile = path; keytabPrincipal = user; Subject subject = new Subject(); LoginContext login; long start = 0; try { login = new LoginContext(HadoopConfiguration.KEYTAB_KERBEROS_CONFIG_NAME, subject); start = System.currentTimeMillis(); login.login(); metrics.loginSuccess.inc(System.currentTimeMillis() - start); loginUser = new UserGroupInformation(subject); loginUser.setLogin(login); loginUser.setAuthenticationMethod(AuthenticationMethod.KERBEROS); } catch (LoginException le) { if (start > 0) { metrics.loginFailure.inc(System.currentTimeMillis() - start); } throw new IOException("Login failure for " + user + " from keytab " + path, le); } LOG.info("Login successful for user " + keytabPrincipal + " using keytab file " + keytabFile); }
/** * Re-Login a user in from the ticket cache. This method assumes that login had happened already. * The Subject field of this UserGroupInformation object is updated to have the new credentials. * * @throws IOException on a failure */ public synchronized void reloginFromTicketCache() throws IOException { if (!isSecurityEnabled() || user.getAuthenticationMethod() != AuthenticationMethod.KERBEROS || !isKrbTkt) return; LoginContext login = getLogin(); if (login == null) { throw new IOException("login must be done first"); } if (!hasSufficientTimeElapsed()) { return; } try { LOG.info("Initiating logout for " + getUserName()); // clear up the kerberos state. But the tokens are not cleared! As per // the Java kerberos login module code, only the kerberos credentials // are cleared login.logout(); // login and also update the subject field of this instance to // have the new credentials (pass it to the LoginContext constructor) login = new LoginContext(HadoopConfiguration.USER_KERBEROS_CONFIG_NAME, getSubject()); LOG.info("Initiating re-login for " + getUserName()); login.login(); setLogin(login); } catch (LoginException le) { throw new IOException("Login failure for " + getUserName(), le); } }
/** * Get the currently logged in user. * * @return the logged in user * @throws IOException if login fails */ public static synchronized UserGroupInformation getLoginUser() throws IOException { if (loginUser == null) { try { Subject subject = new Subject(); LoginContext login; if (isSecurityEnabled()) { login = new LoginContext(HadoopConfiguration.USER_KERBEROS_CONFIG_NAME, subject); } else if (useConfiguredFileAuth) { login = new LoginContext(HadoopConfiguration.FILE_CONFIG_NAME, subject); } else { login = new LoginContext(HadoopConfiguration.SIMPLE_CONFIG_NAME, subject); } login.login(); loginUser = new UserGroupInformation(subject); loginUser.setLogin(login); // loginUser.setAuthenticationMethod(isSecurityEnabled() ? // AuthenticationMethod.KERBEROS : // AuthenticationMethod.SIMPLE); AuthenticationMethod authMethod = AuthenticationMethod.SIMPLE; if (isSecurityEnabled()) { authMethod = AuthenticationMethod.KERBEROS; } else if (useConfiguredFileAuth) { authMethod = AuthenticationMethod.CONFIGFILE; } else { authMethod = AuthenticationMethod.SIMPLE; } loginUser.setAuthenticationMethod(authMethod); loginUser = new UserGroupInformation(login.getSubject()); String fileLocation = System.getenv(HADOOP_TOKEN_FILE_LOCATION); if (fileLocation != null && isSecurityEnabled()) { // load the token storage file and put all of the tokens into the // user. Credentials cred = Credentials.readTokenStorageFiles(fileLocation, conf); for (Token<?> token : cred.getAllTokens()) { loginUser.addToken(token); } } loginUser.spawnAutoRenewalThreadForUserCreds(); } catch (LoginException le) { throw new IOException("failure to login", le); } } return loginUser; }
/** * Re-Login a user in from a keytab file. Loads a user identity from a keytab file and logs them * in. They become the currently logged-in user. This method assumes that {@link * #loginUserFromKeytab(String, String)} had happened already. The Subject field of this * UserGroupInformation object is updated to have the new credentials. * * @throws IOException on a failure */ public synchronized void reloginFromKeytab() throws IOException { if (!isSecurityEnabled() || user.getAuthenticationMethod() != AuthenticationMethod.KERBEROS || !isKeytab) return; LoginContext login = getLogin(); if (login == null || keytabFile == null) { throw new IOException("loginUserFromKeyTab must be done first"); } if (!hasSufficientTimeElapsed()) { return; } long start = 0; try { LOG.info("Initiating logout for " + getUserName()); synchronized (UserGroupInformation.class) { // clear up the kerberos state. But the tokens are not cleared! As per // the Java kerberos login module code, only the kerberos credentials // are cleared login.logout(); // login and also update the subject field of this instance to // have the new credentials (pass it to the LoginContext constructor) login = new LoginContext(HadoopConfiguration.KEYTAB_KERBEROS_CONFIG_NAME, getSubject()); LOG.info("Initiating re-login for " + keytabPrincipal); start = System.currentTimeMillis(); login.login(); metrics.loginSuccess.inc(System.currentTimeMillis() - start); setLogin(login); } } catch (LoginException le) { if (start > 0) { metrics.loginFailure.inc(System.currentTimeMillis() - start); } throw new IOException( "Login failure for " + keytabPrincipal + " from keytab " + keytabFile, le); } }