Example usage for org.apache.zookeeper Shell execCommand

List of usage examples for org.apache.zookeeper Shell execCommand

Introduction

In this page you can find the example usage for org.apache.zookeeper Shell execCommand.

Prototype

public static String execCommand(Map<String, String> env, String... cmd) throws IOException 

Source Link

Document

Static method to execute a shell command.

Usage

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