/**
   * 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);
   }
 }