List of usage examples for org.apache.zookeeper Shell execCommand
public static String execCommand(Map<String, String> env, String... cmd) throws IOException
From source file:org.apache.bookkeeper.sasl.TGTRefreshThread.java
License:Apache License
@Override public void run() { LOG.info("TGT refresh thread started."); while (true) { // renewal thread's main loop. if it exits from here, thread will exit. KerberosTicket tgt = getTGT(); long now = Time.currentWallTime(); long nextRefresh; Date nextRefreshDate;/* w w w. ja v a2 s . co m*/ if (tgt == null) { nextRefresh = now + MIN_TIME_BEFORE_RELOGIN; nextRefreshDate = new Date(nextRefresh); LOG.warn("No TGT found: will try again at {}", nextRefreshDate); } else { nextRefresh = getRefreshTime(tgt); long expiry = tgt.getEndTime().getTime(); Date expiryDate = new Date(expiry); if ((container.isUsingTicketCache()) && (tgt.getEndTime().equals(tgt.getRenewTill()))) { Object[] logPayload = { expiryDate, container.getPrincipal(), container.getPrincipal() }; LOG.error("The TGT cannot be renewed beyond the next expiry date: {}." + "This process will not be able to authenticate new SASL connections after that " + "time (for example, it will not be authenticate a new connection with a Bookie " + "). Ask your system administrator to either increase the " + "'renew until' time by doing : 'modprinc -maxrenewlife {}' within " + "kadmin, or instead, to generate a keytab for {}. Because the TGT's " + "expiry cannot be further extended by refreshing, exiting refresh thread now.", logPayload); return; } // determine how long to sleep from looking at ticket's expiry. // We should not allow the ticket to expire, but we should take into consideration // MIN_TIME_BEFORE_RELOGIN. Will not sleep less than MIN_TIME_BEFORE_RELOGIN, unless doing so // would cause ticket expiration. if ((nextRefresh > expiry) || ((now + MIN_TIME_BEFORE_RELOGIN) > expiry)) { // expiry is before next scheduled refresh). nextRefresh = now; } else { if (nextRefresh < (now + MIN_TIME_BEFORE_RELOGIN)) { // next scheduled refresh is sooner than (now + MIN_TIME_BEFORE_LOGIN). Date until = new Date(nextRefresh); Date newuntil = new Date(now + MIN_TIME_BEFORE_RELOGIN); Object[] logPayload = { until, newuntil, MIN_TIME_BEFORE_RELOGIN / 1000 }; LOG.warn("TGT refresh thread time adjusted from : {} to : {} since " + "the former is sooner than the minimum refresh interval (" + "{} seconds) from now.", logPayload); } nextRefresh = Math.max(nextRefresh, now + MIN_TIME_BEFORE_RELOGIN); } nextRefreshDate = new Date(nextRefresh); if (nextRefresh > expiry) { Object[] logPayload = { nextRefreshDate, expiryDate }; LOG.error("next refresh: {} is later than expiry {}." + " This may indicate a clock skew problem." + "Check that this host and the KDC's " + "hosts' clocks are in sync. Exiting refresh thread.", logPayload); return; } } if (now == nextRefresh) { LOG.info("refreshing now because expiry is before next scheduled refresh time."); } else if (now < nextRefresh) { Date until = new Date(nextRefresh); LOG.info("TGT refresh sleeping until: {}", until.toString()); try { Thread.sleep(nextRefresh - now); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); LOG.warn("TGT renewal thread has been interrupted and will exit."); break; } } else { LOG.error("nextRefresh:{} is in the past: exiting refresh thread. Check" + " clock sync between this host and KDC - (KDC's clock is likely ahead of this host)." + " Manual intervention will be required for this client to successfully authenticate." + " Exiting refresh thread.", nextRefreshDate); break; } if (container.isUsingTicketCache()) { String cmd = container.getConfiguration().getString(SaslConstants.KINIT_COMMAND, SaslConstants.KINIT_COMMAND_DEFAULT); String kinitArgs = "-R"; int retry = 1; while (retry >= 0) { try { if (LOG.isDebugEnabled()) { LOG.debug("running ticket cache refresh command: {} {}", cmd, kinitArgs); } Shell.execCommand(cmd, kinitArgs); break; } catch (Exception e) { if (retry > 0) { --retry; // sleep for 10 seconds try { Thread.sleep(10 * 1000); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); LOG.error("Interrupted while renewing TGT, exiting Login thread"); return; } } else { Object[] logPayload = { cmd, kinitArgs, e.toString(), e }; LOG.warn("Could not renew TGT due to problem running shell command: '{}" + " {}'; exception was:{}. Exiting refresh thread.", logPayload); return; } } } } try { int retry = 1; while (retry >= 0) { try { reLogin(); break; } catch (LoginException le) { if (retry > 0) { --retry; // sleep for 10 seconds. try { Thread.sleep(10 * 1000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); LOG.error("Interrupted during login retry after LoginException:", le); throw le; } } else { LOG.error("Could not refresh TGT for principal: {}.", container.getPrincipal(), le); } } } } catch (LoginException le) { LOG.error("Failed to refresh TGT: refresh thread exiting now.", le); break; } } }
From source file:org.apache.storm.messaging.netty.Login.java
License:Apache License
/** * Login constructor. The constructor starts the thread used * to periodically re-login to the Kerberos Ticket Granting Server. * @param loginContextName// ww w . jav a2 s .com * name of section in JAAS file that will be use to login. * Passed as first param to javax.security.auth.login.LoginContext(). * * @param callbackHandler * Passed as second param to javax.security.auth.login.LoginContext(). * @throws javax.security.auth.login.LoginException * Thrown if authentication fails. */ public Login(final String loginContextName, CallbackHandler callbackHandler) throws LoginException { this.callbackHandler = callbackHandler; login = login(loginContextName); this.loginContextName = loginContextName; subject = login.getSubject(); isKrbTicket = !subject.getPrivateCredentials(KerberosTicket.class).isEmpty(); AppConfigurationEntry entries[] = Configuration.getConfiguration() .getAppConfigurationEntry(loginContextName); for (AppConfigurationEntry entry : entries) { // there will only be a single entry, so this for() loop will only be iterated through once. if (entry.getOptions().get("useTicketCache") != null) { String val = (String) entry.getOptions().get("useTicketCache"); if (val.equals("true")) { isUsingTicketCache = true; } } if (entry.getOptions().get("keyTab") != null) { keytabFile = (String) entry.getOptions().get("keyTab"); isUsingKeytab = true; } if (entry.getOptions().get("principal") != null) { principal = (String) entry.getOptions().get("principal"); } break; } if (!isKrbTicket) { // if no TGT, do not bother with ticket management. return; } // Refresh the Ticket Granting Ticket (TGT) periodically. How often to refresh is determined by the // TGT's existing expiry date and the configured MIN_TIME_BEFORE_RELOGIN. For testing and development, // you can decrease the interval of expiration of tickets (for example, to 3 minutes) by running : // "modprinc -maxlife 3mins <principal>" in kadmin. t = new Thread(new Runnable() { public void run() { LOG.info("TGT refresh thread started."); while (true) { // renewal thread's main loop. if it exits from here, thread will exit. KerberosTicket tgt = getTGT(); long now = System.currentTimeMillis(); long nextRefresh; Date nextRefreshDate; if (tgt == null) { nextRefresh = now + MIN_TIME_BEFORE_RELOGIN; nextRefreshDate = new Date(nextRefresh); LOG.warn("No TGT found: will try again at " + nextRefreshDate); } else { nextRefresh = getRefreshTime(tgt); long expiry = tgt.getEndTime().getTime(); Date expiryDate = new Date(expiry); if ((isUsingTicketCache) && (tgt.getEndTime().equals(tgt.getRenewTill()))) { LOG.error("The TGT cannot be renewed beyond the next expiry date: " + expiryDate + "." + "This process will not be able to authenticate new SASL connections after that " + "time (for example, it will not be authenticate a new connection with a Zookeeper " + "Quorum member). Ask your system administrator to either increase the " + "'renew until' time by doing : 'modprinc -maxrenewlife " + principal + "' within " + "kadmin, or instead, to generate a keytab for " + principal + ". Because the TGT's " + "expiry cannot be further extended by refreshing, exiting refresh thread now."); return; } // determine how long to sleep from looking at ticket's expiry. // We should not allow the ticket to expire, but we should take into consideration // MIN_TIME_BEFORE_RELOGIN. Will not sleep less than MIN_TIME_BEFORE_RELOGIN, unless doing so // would cause ticket expiration. if ((nextRefresh > expiry) || ((now + MIN_TIME_BEFORE_RELOGIN) > expiry)) { // expiry is before next scheduled refresh). nextRefresh = now; } else { if (nextRefresh < (now + MIN_TIME_BEFORE_RELOGIN)) { // next scheduled refresh is sooner than (now + MIN_TIME_BEFORE_LOGIN). Date until = new Date(nextRefresh); Date newuntil = new Date(now + MIN_TIME_BEFORE_RELOGIN); LOG.warn("TGT refresh thread time adjusted from : " + until + " to : " + newuntil + " since " + "the former is sooner than the minimum refresh interval (" + MIN_TIME_BEFORE_RELOGIN / 1000 + " seconds) from now."); } nextRefresh = Math.max(nextRefresh, now + MIN_TIME_BEFORE_RELOGIN); } } if (tgt != null && now > tgt.getEndTime().getTime()) { if ((now - tgt.getEndTime().getTime()) < (10 * MIN_TIME_BEFORE_RELOGIN)) { Date until = new Date(now + MIN_TIME_BEFORE_RELOGIN); LOG.info( "TGT already expired but giving additional 10 minutes past TGT expiry, refresh sleeping until: " + until.toString()); try { Thread.sleep(MIN_TIME_BEFORE_RELOGIN); } catch (InterruptedException ie) { LOG.warn("TGT renewal thread has been interrupted and will exit."); return; } } else { LOG.error("nextRefresh:" + new Date(nextRefresh) + " is in the past: exiting refresh thread. Check" + " clock sync between this host and KDC - (KDC's clock is likely ahead of this host)." + " Manual intervention will be required for this client to successfully authenticate." + " Exiting worker!."); Runtime.getRuntime().exit(-3); } } else if (now < nextRefresh) { Date until = new Date(nextRefresh); LOG.info("TGT refresh sleeping until: " + until.toString()); try { Thread.sleep(nextRefresh - now); } catch (InterruptedException ie) { LOG.warn("TGT renewal thread has been interrupted and will exit."); return; } } if (isUsingTicketCache) { String cmd = "/usr/bin/kinit"; if (System.getProperty("zookeeper.kinit") != null) { cmd = System.getProperty("zookeeper.kinit"); } String kinitArgs = "-R"; int retry = 1; while (retry >= 0) { try { LOG.debug("running ticket cache refresh command: " + cmd + " " + kinitArgs); Shell.execCommand(cmd, kinitArgs); break; } catch (Exception e) { if (retry > 0) { --retry; // sleep for 10 seconds try { Thread.sleep(10 * 1000); } catch (InterruptedException ie) { LOG.error("Interrupted while renewing TGT, exiting Login thread"); return; } } else { LOG.warn("Could not renew TGT due to problem running shell command: '" + cmd + " " + kinitArgs + "'" + "; exception was:" + e + ". Exiting refresh thread.", e); return; } } } } try { int retry = 1; while (retry >= 0) { try { reLogin(); break; } catch (LoginException le) { if (retry > 0) { --retry; // sleep for 10 seconds. try { Thread.sleep(10 * 1000); } catch (InterruptedException e) { LOG.error("Interrupted during login retry after LoginException:", le); throw le; } } else { LOG.error("Could not refresh TGT for principal: " + principal + ".", le); } } } } catch (LoginException le) { LOG.error("Failed to refresh TGT: refresh thread exiting now.", le); break; } } } }); t.setName("Refresh-TGT"); t.setDaemon(true); }