// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

#include "rpc/authentication.h"

#include <stdio.h>
#include <signal.h>
#include <boost/algorithm/string.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int.hpp>
#include <boost/filesystem.hpp>
#include <gutil/casts.h>
#include <gutil/strings/escaping.h>
#include <gutil/strings/split.h>
#include <gutil/strings/strip.h>
#include <gutil/strings/substitute.h>
#include <random>
#include <string>
#include <vector>
#include <thrift/Thrift.h>
#include <transport/TSasl.h>
#include <transport/TSaslServerTransport.h>
#include <gflags/gflags.h>

#include <ldap.h>

#include "exec/kudu-util.h"
#include "kudu/rpc/sasl_common.h"
#include "kudu/security/gssapi.h"
#include "kudu/security/init.h"
#include "rpc/auth-provider.h"
#include "rpc/cookie-util.h"
#include "rpc/thrift-server.h"
#include "transport/THttpServer.h"
#include "transport/TSaslClientTransport.h"
#include "util/auth-util.h"
#include "util/coding-util.h"
#include "util/debug-util.h"
#include "util/error-util.h"
#include "util/network-util.h"
#include "util/os-util.h"
#include "util/promise.h"
#include "util/time.h"

#include <sys/types.h>    // for stat system call
#include <sys/stat.h>     // for stat system call
#include <unistd.h>       // for stat system call

#include "common/names.h"

using boost::algorithm::is_any_of;
using boost::algorithm::replace_all;
using boost::algorithm::split;
using boost::algorithm::trim;
using boost::mt19937;
using boost::uniform_int;
using namespace apache::thrift;
using namespace apache::thrift::transport;
using namespace boost::filesystem;   // for is_regular(), is_absolute()
using namespace strings;

DECLARE_string(keytab_file);
DECLARE_string(principal);
DECLARE_string(be_principal);
DECLARE_string(krb5_ccname);
DECLARE_string(krb5_conf);
DECLARE_string(krb5_debug_file);

// Defined in kudu/security/init.cc
DECLARE_bool(use_system_auth_to_local);

DECLARE_int64(max_cookie_lifetime_s);

DEFINE_string(sasl_path, "", "Colon separated list of paths to look for SASL "
    "security library plugins.");
DEFINE_bool(enable_ldap_auth, false,
    "If true, use LDAP authentication for client connections");

DEFINE_string(ldap_uri, "", "The URI of the LDAP server to authenticate users against");
DEFINE_bool(ldap_tls, false, "If true, use the secure TLS protocol to connect to the LDAP"
    " server");
DEFINE_string(ldap_ca_certificate, "", "The full path to the certificate file used to"
    " authenticate the LDAP server's certificate for SSL / TLS connections.");
DEFINE_bool(ldap_passwords_in_clear_ok, false, "If set, will allow LDAP passwords "
    "to be sent in the clear (without TLS/SSL) over the network.  This option should not "
    "be used in production environments" );
DEFINE_bool(ldap_allow_anonymous_binds, false, "(Advanced) If true, LDAP authentication "
    "with a blank password (an 'anonymous bind') is allowed by Impala.");
DEFINE_bool(ldap_manual_config, false, "Obsolete; Ignored");
DEFINE_string(ldap_domain, "", "If set, Impala will try to bind to LDAP with a name of "
    "the form <userid>@<ldap_domain>");
DEFINE_string(ldap_baseDN, "", "If set, Impala will try to bind to LDAP with a name of "
    "the form uid=<userid>,<ldap_baseDN>");
DEFINE_string(ldap_bind_pattern, "", "If set, Impala will try to bind to LDAP with a name"
     " of <ldap_bind_pattern>, but where the string #UID is replaced by the user ID. Use"
     " to control the bind name precisely; do not set --ldap_domain or --ldap_baseDN with"
     " this option");
DEFINE_string(internal_principals_whitelist, "hdfs", "(Advanced) Comma-separated list of "
    " additional usernames authorized to access Impala's internal APIs. Defaults to "
    "'hdfs' which is the system user that in certain deployments must access "
    "catalog server APIs.");

namespace impala {

// Sasl callbacks.  Why are these here?  Well, Sasl isn't that bright, and
// instead of copying the callbacks, it just saves a pointer to them.  If
// they're on the stack, this means that they *go away* when the function
// exits... so make these global and static here, and fill them in below.
// Vectors are used for the three latter items because that's what the thrift
// interface expects.
//
// The way the callbacks work is that the Sasl code will look for a registered
// callback in the connection-specific callback list (one of the latter three),
// and if not found, then look for a registered callback in the
// "GENERAL_CALLBACKS" list.
static sasl_callback_t GENERAL_CALLBACKS[5];        // Applies to all connections
static vector<sasl_callback_t> KERB_INT_CALLBACKS;  // Internal kerberos connections
static vector<sasl_callback_t> KERB_EXT_CALLBACKS;  // External kerberos connections
static vector<sasl_callback_t> LDAP_EXT_CALLBACKS;  // External LDAP connections

// The name of the application passed to Sasl which will retain reference to it.
// This is initialized the first time InitAuth() is called. Future call must pass
// the same 'appname' or InitAuth() will fail.
static string APP_NAME;

// Constants for the two Sasl mechanisms we support
static const string KERBEROS_MECHANISM = "GSSAPI";
static const string PLAIN_MECHANISM = "PLAIN";

// Required prefixes for ldap URIs:
static const string LDAP_URI_PREFIX = "ldap://";
static const string LDAPS_URI_PREFIX = "ldaps://";

// We implement an "auxprop" plugin for the Sasl layer in order to have a hook in which
// to log messages about the start of authentication. This is that plugin's name.
static const string IMPALA_AUXPROP_PLUGIN = "impala-auxprop";

AuthManager* AuthManager::auth_manager_ = new AuthManager();

// This Sasl callback is called when the underlying cyrus-sasl layer has
// something that it would like to say.  We catch it and turn it into the
// appropriate LOG() call.
//
// context: Passed a (char *) that comes from the initialization, used
//          to describe the kerb|ldap internal|external context
// level: The SASL_LOG_ level
// message: The message to log
// Return: Always SASL_OK, unless message is NULL, then it's SASL_BADPARAM.
static int SaslLogCallback(void* context, int level, const char* message) {
  if (message == NULL) return SASL_BADPARAM;
  const char* authctx = (context == NULL) ? "Unknown" :
      reinterpret_cast<const char*>(context);

  switch (level) {
  case SASL_LOG_NONE:  // "Don't log anything"
  case SASL_LOG_PASS:  // "Traces... including passwords" - don't log!
    break;
  case SASL_LOG_ERR:   // "Unusual errors"
  case SASL_LOG_FAIL:  // "Authentication failures"
    LOG(ERROR) << "SASL message (" << authctx << "): " << message;
    break;
  case SASL_LOG_WARN:  // "Non-fatal warnings"
    LOG(WARNING) << "SASL message (" << authctx << "): " << message;
    break;
  case SASL_LOG_NOTE:  // "More verbose than WARN"
    LOG(INFO) << "SASL message (" << authctx << "): " << message;
    break;
  case SASL_LOG_DEBUG: // "More verbose than NOTE"
    VLOG(1) << "SASL message (" << authctx << "): " << message;
    break;
  case SASL_LOG_TRACE: // "Traces of internal protocols"
  default:
    VLOG(3) << "SASL message (" << authctx << "): " << message;
    break;
  }

  return SASL_OK;
}

// This callback is only called when we're providing LDAP authentication. This "check
// pass" callback is our hook to ask the real LDAP server if we're allowed to log in or
// not. We can be thought of as a proxy for LDAP logins - the user gives their password
// to us, and we pass it to the real LDAP server.
//
// Note that this method uses ldap_sasl_bind_s(), which does *not* provide any security
// to the connection between Impala and the LDAP server. You must either set --ldap_tls,
// or have a URI which has "ldaps://" as the scheme in order to get a secure connection.
// Use --ldap_ca_certificate to specify the location of the certificate used to confirm
// the authenticity of the LDAP server certificate.
//
// user: The username to authenticate
// pass: The password to use
// passlen: The length of pass
// Return: true on success, false otherwise
static bool LdapCheckPass(const char* user, const char* pass, unsigned passlen) {
  if (passlen == 0 && !FLAGS_ldap_allow_anonymous_binds) {
    // Disable anonymous binds.
    return false;
  }

  LDAP* ld;
  int rc = ldap_initialize(&ld, FLAGS_ldap_uri.c_str());
  if (rc != LDAP_SUCCESS) {
    LOG(WARNING) << "Could not initialize connection with LDAP server ("
                 << FLAGS_ldap_uri << "). Error: " << ldap_err2string(rc);
    return false;
  }

  // Force the LDAP version to 3 to make sure TLS is supported.
  int ldap_ver = 3;
  ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &ldap_ver);

  // If -ldap_tls is turned on, and the URI is ldap://, issue a STARTTLS operation.
  // Note that we'll ignore -ldap_tls when using ldaps:// because we've already
  // got a secure connection (and the LDAP server will reject the STARTTLS).
  if (FLAGS_ldap_tls && (FLAGS_ldap_uri.find(LDAP_URI_PREFIX) == 0)) {
    int tls_rc = ldap_start_tls_s(ld, NULL, NULL);
    if (tls_rc != LDAP_SUCCESS) {
      LOG(WARNING) << "Could not start TLS secure connection to LDAP server ("
                   << FLAGS_ldap_uri << "). Error: " << ldap_err2string(tls_rc);
      ldap_unbind_ext(ld, NULL, NULL);
      return false;
    }
    VLOG(2) << "Started TLS connection with LDAP server: " << FLAGS_ldap_uri;
  }

  // Map the user string into an acceptable LDAP "DN" (distinguished name)
  string user_str = user;
  if (!FLAGS_ldap_domain.empty()) {
    // Append @domain if there isn't already an @ in the user string.
    if (user_str.find("@") == string::npos) {
      user_str = Substitute("$0@$1", user_str, FLAGS_ldap_domain);
    }
  } else if (!FLAGS_ldap_baseDN.empty()) {
    user_str = Substitute("uid=$0,$1", user_str, FLAGS_ldap_baseDN);
  } else if (!FLAGS_ldap_bind_pattern.empty()) {
    user_str = FLAGS_ldap_bind_pattern;
    replace_all(user_str, "#UID", user);
  }

  // Map the password into a credentials structure
  struct berval cred;
  cred.bv_val = const_cast<char*>(pass);
  cred.bv_len = passlen;

  VLOG_QUERY << "Trying simple LDAP bind for: " << user_str;

  rc = ldap_sasl_bind_s(ld, user_str.c_str(), LDAP_SASL_SIMPLE, &cred,
      NULL, NULL, NULL);
  // Free ld
  ldap_unbind_ext(ld, NULL, NULL);
  if (rc != LDAP_SUCCESS) {
    LOG(WARNING) << "LDAP authentication failure for " << user_str
                 << " : " << ldap_err2string(rc);
    return false;
  }

  VLOG_QUERY << "LDAP bind successful";

  return true;
}

// Wrapper around the function we use to check passwords with LDAP which converts the
// return value to something appropriate for SASL.
//
// conn: The Sasl connection struct, which we ignore
// context: Ignored; always NULL
// user: The username to authenticate
// pass: The password to use
// passlen: The length of pass
// propctx: Ignored - properties requested
// Return: SASL_OK on success, SASL_FAIL otherwise
int SaslLdapCheckPass(sasl_conn_t* conn, void* context, const char* user,
    const char* pass, unsigned passlen, struct propctx* propctx) {
  return LdapCheckPass(user, pass, passlen) ? SASL_OK : SASL_FAIL;
}

// Sasl wants a way to ask us about some options, this function provides
// answers.  Currently we only support telling Sasl about the log_level; other
// items are printed out for curiosity's sake, but otherwise ignored.
//
// context: Ignored, always NULL
// plugin_name: If applicable, the name of the plugin making the
//              request.  NULL if it's a general option.
// option: The name of the configurable parameter
// result: A char * array to hold our answer
// len: Bytes at result
// Return: SASL_OK for things we deal with; SASL_FAIL otherwise.  The
//         cyrus-sasl code rarely checks the return value; it's more
//         interested in whether we fill in *result or not.
static int SaslGetOption(void* context, const char* plugin_name, const char* option,
    const char** result, unsigned* len) {

  if (plugin_name == NULL) {
    if (strcmp("log_level", option) == 0) {
      int level = SASL_LOG_WARN;
      if (VLOG_CONNECTION_IS_ON) {
        level = SASL_LOG_DEBUG;
      } else if (VLOG_ROW_IS_ON) {
        level = SASL_LOG_TRACE;
      }
      static char buf[4];
      snprintf(buf, 4, "%d", level);
      *result = buf;
      if (len != NULL) *len = strlen(buf);
      return SASL_OK;
    } else if (strcmp("auxprop_plugin", option) == 0) {
      *result = IMPALA_AUXPROP_PLUGIN.c_str();
      if (len != NULL) *len = strlen(*result);
      return SASL_OK;
    }

    VLOG(3) << "Sasl general option " << option << " requested";
    return SASL_FAIL;
  }

  VLOG(3) << "Sasl option " << plugin_name << " : "
          << option << " requested";
  return SASL_FAIL;
}

// The "auxprop" plugin interface was intended to be a database service for the "glue"
// layer between the mechanisms and applications.  We, however, hijack this interface
// simply in order to provide an audit message prior to that start of authentication.
#if SASL_VERSION_FULL >= ((2 << 16) | (1 << 8) | 25)
static int ImpalaAuxpropLookup(void* glob_context, sasl_server_params_t* sparams,
#else
static void ImpalaAuxpropLookup(void* glob_context, sasl_server_params_t* sparams,
#endif
    unsigned int flags, const char* user, unsigned ulen) {
  // This callback is called twice, once with this flag clear, and once with
  // this flag set.  We only want to log this message once, so only log it when
  // the flag is clear.
  if ((flags & SASL_AUXPROP_AUTHZID) == 0) {
    string ustr(user, ulen);
    VLOG(2) << "Attempting to authenticate user \"" << ustr << "\"";
  }
#if SASL_VERSION_FULL >= ((2 << 16) | (1 << 8) | 25)
  return SASL_OK;
#endif
}

// Singleton structure used to register our auxprop plugin with Sasl
static sasl_auxprop_plug_t impala_auxprop_plugin = {
  0, // feature flag
  0, // 'spare'
  NULL, // global plugin state
  NULL, // Free global state callback
  &ImpalaAuxpropLookup, // Auxprop lookup method
  const_cast<char*>(IMPALA_AUXPROP_PLUGIN.c_str()), // Name of plugin
  NULL // Store property callback
};

// This is a Sasl callback that's called in order to register our "auxprop"
// plugin.  We give it the structure above, which installs ImpalaAuxpropLookup
// as the lookup method.
int ImpalaAuxpropInit(const sasl_utils_t* utils, int max_version, int* out_version,
    sasl_auxprop_plug_t** plug, const char* plugname) {
  VLOG(2) << "Initializing Impala SASL plugin: " << plugname;
  *plug = &impala_auxprop_plugin;
  *out_version = max_version;
  return SASL_OK;
}

// This Sasl callback will tell us what files Sasl is trying to access.  It's
// here just for curiousity's sake at the moment. It might be useful for
// telling us precisely which plugins have been found.
//
// context: Ignored, always NULL
// file: The file being accessed
// type: What type of thing is it: plugin, config file, etc
// Return: SASL_OK
static int SaslVerifyFile(void* context, const char* file,
    sasl_verify_type_t type ) {
  switch(type) {
    case SASL_VRFY_PLUGIN:
      VLOG(2) << "Sasl found plugin " << file;
      break;
    case SASL_VRFY_CONF:
      VLOG(2) << "Sasl trying to access config file " << file;
      break;
    case SASL_VRFY_PASSWD:
      VLOG(2) << "Sasl accessing password file " << file;
      break;
    default:
      VLOG(2) << "Sasl found other file " << file;
      break;
  }
  return SASL_OK;
}

// Authorizes authenticated users on an internal connection after validating that the
// first components of the 'requested_user' and our principal are the same.
//
// conn: Sasl connection - Ignored
// context: Always NULL except for testing.
// requested_user: The identity/username to authorize
// rlen: Length of above
// auth_identity: "The identity associated with the secret"
// alen: Length of above
// def_realm: Default user realm
// urlen: Length of above
// propctx: Auxiliary properties - Ignored
// Return: SASL_OK
int SaslAuthorizeInternal(sasl_conn_t* conn, void* context,
    const char* requested_user, unsigned rlen,
    const char* auth_identity, unsigned alen,
    const char* def_realm, unsigned urlen,
    struct propctx* propctx) {
  string requested_principal(requested_user, rlen);
  vector<string> names;
  split(names, requested_principal, is_any_of("/@"));

  if (names.size() != 3) {
    LOG(INFO) << "Kerberos principal should be of the form: "
              << "<service>/<hostname>@<realm> - got: " << requested_user;
    return SASL_BADAUTH;
  }
  SecureAuthProvider* internal_auth_provider;
  if (context == NULL) {
    internal_auth_provider = static_cast<SecureAuthProvider*>(
        AuthManager::GetInstance()->GetInternalAuthProvider());
  } else {
    // Branch should only be taken for testing, where context is used to inject an auth
    // provider.
    internal_auth_provider = static_cast<SecureAuthProvider*>(context);
  }

  vector<string> whitelist;
  split(whitelist, FLAGS_internal_principals_whitelist, is_any_of(","));
  whitelist.push_back(internal_auth_provider->service_name());
  for (string& s: whitelist) {
    trim(s);
    if (s.empty()) continue;
    if (names[0] == s) {
      // We say "principal" here becase this is for internal communication, and hence
      // ought always be --principal or --be_principal
      VLOG(1) << "Successfully authenticated principal \"" << requested_principal
              << "\" on an internal connection";
      return SASL_OK;
    }
  }
  string expected_names = FLAGS_internal_principals_whitelist.empty() ? "" :
      Substitute(" or one of $0", FLAGS_internal_principals_whitelist);
  LOG(INFO) << "Principal \"" << requested_principal << "\" not authenticated. "
            << "Reason: 'service' does not match from <service>/<hostname>@<realm>.\n"
            << "Got: " << names[0]
            << ". Expected: " << internal_auth_provider->service_name() << expected_names;
  return SASL_BADAUTH;
}

// This callback could be used to authorize or restrict access to certain
// users.  Currently it is used to log a message that we successfully
// authenticated with a user on an external connection.
//
// conn: Sasl connection - Ignored
// context: Ignored, always NULL
// requested_user: The identity/username to authorize
// rlen: Length of above
// auth_identity: "The identity associated with the secret"
// alen: Length of above
// def_realm: Default user realm
// urlen: Length of above
// propctx: Auxiliary properties - Ignored
// Return: SASL_OK
static int SaslAuthorizeExternal(sasl_conn_t* conn, void* context,
    const char* requested_user, unsigned rlen,
    const char* auth_identity, unsigned alen,
    const char* def_realm, unsigned urlen,
    struct propctx* propctx) {
  LOG(INFO) << "Successfully authenticated client user \""
            << string(requested_user, rlen) << "\"";
  return SASL_OK;
}

// Sasl callback - where to look for plugins.  When SASL is dynamically linked, the plugin
// path is embedded in the library. However, for backwards compatibility in Impala, we
// provided the possibility to define a custom SASL plugin path that may override the
// system default. This function is only used, when the user actively chooses to manually
// define a custom SASL path, otherwise the automatic path resolution from the SASL
// library is used.
//
// context: Ignored, always NULL
// path: We return the plugin paths here.
// Return: SASL_OK
static int SaslGetPath(void* context, const char** path) {
  *path = FLAGS_sasl_path.c_str();
  return SASL_OK;
}

bool CookieAuth(ThriftServer::ConnectionContext* connection_context,
    const AuthenticationHash& hash, const std::string& cookie_header) {
  string username;
  Status cookie_status = AuthenticateCookie(hash, cookie_header, &username);
  if (cookie_status.ok()) {
    connection_context->username = username;
    return true;
  }

  LOG(INFO) << "Invalid cookie provided: " << cookie_header
            << " from: " << TNetworkAddressToString(connection_context->network_address)
            << ": " << cookie_status.GetDetail();
  connection_context->return_headers.push_back(
      Substitute("Set-Cookie: $0", GetDeleteCookie()));
  return false;
}

bool BasicAuth(ThriftServer::ConnectionContext* connection_context,
    const AuthenticationHash& hash, const std::string& base64) {
  if (base64.empty()) {
    connection_context->return_headers.push_back("WWW-Authenticate: Basic");
    return false;
  }
  string decoded;
  if (!Base64Unescape(base64, &decoded)) {
    LOG(ERROR) << "Failed to decode base64 auth string from: "
               << TNetworkAddressToString(connection_context->network_address);
    connection_context->return_headers.push_back("WWW-Authenticate: Basic");
    return false;
  }
  std::size_t colon = decoded.find(':');
  if (colon == std::string::npos) {
    LOG(ERROR) << "Auth string must be in the form '<username>:<password>' from: "
               << TNetworkAddressToString(connection_context->network_address);
    connection_context->return_headers.push_back("WWW-Authenticate: Basic");
    return false;
  }
  string username = decoded.substr(0, colon);
  string password = decoded.substr(colon + 1);
  bool ret = LdapCheckPass(username.c_str(), password.c_str(), password.length());
  if (ret) {
    // Authenication was successful, so set the username on the connection.
    connection_context->username = username;
    // Create a cookie to return.
    connection_context->return_headers.push_back(
        Substitute("Set-Cookie: $0", GenerateCookie(username, hash)));
    return true;
  }
  connection_context->return_headers.push_back("WWW-Authenticate: Basic");
  return false;
}

// Performs a step of SPNEGO auth for the HTTP transport and sets the username on
// 'connection_context' if auth is successful. 'header_token' is the value from an
// 'Authorization: Negotiate" header. Returns true if the step was successful and sets
// 'is_complete' to indicate if more steps are needed. Returns false if an error was
// encountered and the connection should be closed.
bool NegotiateAuth(ThriftServer::ConnectionContext* connection_context,
    const AuthenticationHash& hash, const std::string& header_token, bool* is_complete) {
  if (header_token.empty()) {
    connection_context->return_headers.push_back("WWW-Authenticate: Negotiate");
    *is_complete = false;
    return false;
  }
  std::string token;
  // Note: according to RFC 2616, the correct format for the header is:
  // 'Authorization: Negotiate <token>'. However, beeline incorrectly adds an additional
  // ':', i.e. 'Authorization: Negotiate: <token>'. We handle that here.
  TryStripPrefixString(header_token, ": ", &token);
  string resp_token;
  string username;
  kudu::Status spnego_status =
      kudu::gssapi::SpnegoStep(token, &resp_token, is_complete, &username);
  if (spnego_status.ok()) {
    if (!resp_token.empty()) {
      string resp_header = Substitute("WWW-Authenticate: Negotiate $0", resp_token);
      connection_context->return_headers.push_back(resp_header);
    }
    if (*is_complete) {
      if (username.empty()) {
        spnego_status = kudu::Status::RuntimeError(
            "SPNEGO indicated complete, but got empty principal");
        // Crash in debug builds, but fall through to treating as an error in release.
        LOG(DFATAL) << "Got no authenticated principal for SPNEGO-authenticated "
                    << " connection from "
                    << TNetworkAddressToString(connection_context->network_address)
                    << ": " << spnego_status.ToString();
      } else {
        // Authentication was successful, so set the username on the connection.
        connection_context->username = username;
        // Create a cookie to return.
        connection_context->return_headers.push_back(
            Substitute("Set-Cookie: $0", GenerateCookie(username, hash)));
      }
    }
  } else {
    LOG(WARNING) << "Failed to authenticate request from "
                 << TNetworkAddressToString(connection_context->network_address)
                 << " via SPNEGO: " << spnego_status.ToString();
  }
  return spnego_status.ok();
}

vector<string> ReturnHeaders(ThriftServer::ConnectionContext* connection_context) {
  return std::move(connection_context->return_headers);
}

// Takes the path component of an HTTP request and parses it. For now, we only care about
// the 'doAs' parameter.
bool HttpPathFn(ThriftServer::ConnectionContext* connection_context, const string& path,
    string* err_msg) {
  // 'path' should be of the form '/.*[?<key=value>[&<key=value>...]]'
  vector<string> split = Split(path, delimiter::Limit("?", 1));
  if (split.size() == 2) {
    for (auto pair : Split(split[1], "&")) {
      vector<string> key_value = Split(pair, delimiter::Limit("=", 1));
      if (key_value.size() == 2 && key_value[0] == "doAs") {
        string decoded;
        if (!UrlDecode(key_value[1], &decoded)) {
          *err_msg = Substitute(
              "Could not decode 'doAs' parameter from HTTP request with path: $0", path);
          return false;
        } else {
          connection_context->do_as_user = decoded;
        }
        break;
      }
    }
  }
  return true;
}

namespace {

// SASL requires mutexes for thread safety, but doesn't implement
// them itself. So, we have to hook them up to our mutex implementation.
static void* SaslMutexAlloc() {
  return static_cast<void*>(new mutex());
}
static void SaslMutexFree(void* m) {
  delete static_cast<mutex*>(m);
}
static int SaslMutexLock(void* m) {
  static_cast<mutex*>(m)->lock();
  return 0; // indicates success.
}
static int SaslMutexUnlock(void* m) {
  static_cast<mutex*>(m)->unlock();
  return 0; // indicates success.
}

void SaslSetMutex() {
  sasl_set_mutex(&SaslMutexAlloc, &SaslMutexLock, &SaslMutexUnlock, &SaslMutexFree);
}

}


Status InitAuth(const string& appname) {
  if (APP_NAME.empty()) {
    APP_NAME = appname;
  } else if (APP_NAME != appname) {
    return Status(TErrorCode::SASL_APP_NAME_MISMATCH, APP_NAME, appname);
  }

  // Setup basic callbacks for Sasl. We initialize SASL always since KRPC expects it to
  // be initialized.
  // Good idea to have logging everywhere
  GENERAL_CALLBACKS[0].id = SASL_CB_LOG;
  GENERAL_CALLBACKS[0].proc = (int (*)())&SaslLogCallback;
  GENERAL_CALLBACKS[0].context = ((void *)"General");

  int arr_offset = 0;
  if (!FLAGS_sasl_path.empty()) {
    // Need this here so we can find available mechanisms
    GENERAL_CALLBACKS[1].id = SASL_CB_GETPATH;
    GENERAL_CALLBACKS[1].proc = (int (*)())&SaslGetPath;
    GENERAL_CALLBACKS[1].context = NULL;
    arr_offset = 1;
  }

  // Allows us to view and set some options
  GENERAL_CALLBACKS[1 + arr_offset].id = SASL_CB_GETOPT;
  GENERAL_CALLBACKS[1 + arr_offset].proc = (int (*)())&SaslGetOption;
  GENERAL_CALLBACKS[1 + arr_offset].context = NULL;

  // For curiosity, let's see what files are being touched.
  GENERAL_CALLBACKS[2 + arr_offset].id = SASL_CB_VERIFYFILE;
  GENERAL_CALLBACKS[2 + arr_offset].proc = (int (*)())&SaslVerifyFile;
  GENERAL_CALLBACKS[2 + arr_offset].context = NULL;

  GENERAL_CALLBACKS[3 + arr_offset].id = SASL_CB_LIST_END;

  // Other than the general callbacks, we only setup other SASL things as required.
  if (FLAGS_enable_ldap_auth || IsKerberosEnabled()) {
    if (!FLAGS_principal.empty()) {
      // Callbacks for when we're a Kerberos Sasl internal connection.  Just do logging.
      KERB_INT_CALLBACKS.resize(3);

      KERB_INT_CALLBACKS[0].id = SASL_CB_LOG;
      KERB_INT_CALLBACKS[0].proc = (int (*)())&SaslLogCallback;
      KERB_INT_CALLBACKS[0].context = ((void *)"Kerberos (internal)");

      KERB_INT_CALLBACKS[1].id = SASL_CB_PROXY_POLICY;
      KERB_INT_CALLBACKS[1].proc = (int (*)())&SaslAuthorizeInternal;
      KERB_INT_CALLBACKS[1].context = NULL;

      KERB_INT_CALLBACKS[2].id = SASL_CB_LIST_END;

      // Our externally facing Sasl callbacks for Kerberos communication
      KERB_EXT_CALLBACKS.resize(3);

      KERB_EXT_CALLBACKS[0].id = SASL_CB_LOG;
      KERB_EXT_CALLBACKS[0].proc = (int (*)())&SaslLogCallback;
      KERB_EXT_CALLBACKS[0].context = ((void *)"Kerberos (external)");

      KERB_EXT_CALLBACKS[1].id = SASL_CB_PROXY_POLICY;
      KERB_EXT_CALLBACKS[1].proc = (int (*)())&SaslAuthorizeExternal;
      KERB_EXT_CALLBACKS[1].context = NULL;

      KERB_EXT_CALLBACKS[2].id = SASL_CB_LIST_END;
    }

    if (FLAGS_enable_ldap_auth) {
      // Our external server-side SASL callbacks for LDAP communication
      LDAP_EXT_CALLBACKS.resize(4);

      LDAP_EXT_CALLBACKS[0].id = SASL_CB_LOG;
      LDAP_EXT_CALLBACKS[0].proc = (int (*)())&SaslLogCallback;
      LDAP_EXT_CALLBACKS[0].context = ((void *)"LDAP");

      LDAP_EXT_CALLBACKS[1].id = SASL_CB_PROXY_POLICY;
      LDAP_EXT_CALLBACKS[1].proc = (int (*)())&SaslAuthorizeExternal;
      LDAP_EXT_CALLBACKS[1].context = NULL;

      // This last callback is where we take the password and turn around and
      // call into openldap.
      LDAP_EXT_CALLBACKS[2].id = SASL_CB_SERVER_USERDB_CHECKPASS;
      LDAP_EXT_CALLBACKS[2].proc = (int (*)())&SaslLdapCheckPass;
      LDAP_EXT_CALLBACKS[2].context = NULL;

      LDAP_EXT_CALLBACKS[3].id = SASL_CB_LIST_END;
    }

    // Kudu Client and Kudu RPC shouldn't attempt to initialize SASL which would conflict
    // with Impala's SASL initialization. This must be called before any Kudu RPC objects
    // and KuduClients are created to ensure that Kudu doesn't init SASL first, and this
    // returns an error if Kudu has already initialized SASL.
    KUDU_RETURN_IF_ERROR(kudu::rpc::DisableSaslInitialization(),
        "Unable to disable Kudu RPC SASL initialization.");
    if (KuduIsAvailable()) {
      KUDU_RETURN_IF_ERROR(kudu::client::DisableSaslInitialization(),
          "Unable to disable Kudu SASL initialization.");
    }
  }

  SaslSetMutex();
  try {
    // We assume all impala processes are both server and client.
    sasl::TSaslServer::SaslInit(GENERAL_CALLBACKS, APP_NAME.c_str());
    sasl::TSaslClient::SaslInit(GENERAL_CALLBACKS);
  } catch (sasl::SaslServerImplException& e) {
    stringstream err_msg;
    err_msg << "Could not initialize Sasl library: " << e.what();
    return Status(err_msg.str());
  }

  // Add our auxprop plugin, which gives us a hook before authentication
  int rc = sasl_auxprop_add_plugin(IMPALA_AUXPROP_PLUGIN.c_str(), &ImpalaAuxpropInit);
  if (rc != SASL_OK) {
    return Status(Substitute("Error adding Sasl auxprop plugin: $0",
            sasl_errstring(rc, NULL, NULL)));
  }

  // Initializes OpenSSL.
  RETURN_IF_ERROR(AuthManager::GetInstance()->Init());

  // Prevent Kudu from re-initializing OpenSSL.
  if (KuduIsAvailable()) {
    KUDU_RETURN_IF_ERROR(kudu::client::DisableOpenSSLInitialization(),
        "Unable to disable Kudu SSL initialization.");
  }
  return Status::OK();
}

// Ensure that /var/tmp (the location of the Kerberos replay cache) has drwxrwxrwt
// permissions.  If it doesn't, Kerberos will be unhappy in a way that's very difficult
// to debug.  We do this using direct stat() calls because boost doesn't support the
// detail we need.
Status CheckReplayCacheDirPermissions() {
  struct stat st;

  if (stat("/var/tmp", &st) < 0) {
    return Status(Substitute("Problem accessing /var/tmp: $0", GetStrErrMsg()));
  }

  if (!(st.st_mode & S_IFDIR)) {
    return Status("Error: /var/tmp is not a directory");
  }

  if ((st.st_mode & 01777) != 01777) {
    return Status("Error: The permissions on /var/tmp must precisely match "
        "\"drwxrwxrwt\". This directory is used by the Kerberos replay cache. To "
        "rectify this issue, run \"chmod 01777 /var/tmp\" as root.");
  }

  return Status::OK();
}

Status SecureAuthProvider::InitKerberos(
    const string& principal, const string& keytab_file) {
  principal_ = principal;
  keytab_file_ = keytab_file;
  // The logic here is that needs_kinit_ is false unless we are the internal
  // auth provider and we support kerberos.
  needs_kinit_ = is_internal_;

  RETURN_IF_ERROR(ParseKerberosPrincipal(
      principal_, &service_name_, &hostname_, &realm_));

  LOG(INFO) << "Using " << (is_internal_ ? "internal" : "external")
            << " kerberos principal \"" << service_name_ << "/"
            << hostname_ << "@" << realm_ << "\"";

  return Status::OK();
}

// For the environment variable attr, append "-Dthing=thingval" if "thing" is not already
// in the current attr's value.
static Status EnvAppend(const string& attr, const string& thing, const string& thingval) {
  // Carefully append to attr. There are three distinct cases:
  // 1. Attr doesn't exist: set it
  // 2. Attr exists, and doesn't contain thing: append to it
  // 3. Attr exists, and already contains thing: do nothing
  string current_val;
  char* current_val_c = getenv(attr.c_str());
  if (current_val_c != NULL) {
    current_val = current_val_c;
  }

  if (!current_val.empty() && (current_val.find(thing) != string::npos)) {
    // Case 3 above
    return Status::OK();
  }

  stringstream val_out;
  if (!current_val.empty()) {
    // Case 2 above
    val_out << current_val << " ";
  }
  val_out << "-D" << thing << "=" << thingval;

  if (setenv(attr.c_str(), val_out.str().c_str(), 1) < 0) {
    return Status(Substitute("Bad $0=$1 value: Could not set environment variable $2: $3",
        thing, thingval, attr, GetStrErrMsg()));
  }

  return Status::OK();
}

Status AuthManager::InitKerberosEnv() {
  DCHECK(!FLAGS_principal.empty());

  RETURN_IF_ERROR(CheckReplayCacheDirPermissions());

  if (!is_regular(FLAGS_keytab_file)) {
    return Status(Substitute("Bad --keytab_file value: The file $0 is not a "
        "regular file", FLAGS_keytab_file));
  }

  // Set the keytab name in the environment so that Sasl Kerberos and kinit can
  // find and use it.
  if (setenv("KRB5_KTNAME", FLAGS_keytab_file.c_str(), 1)) {
    return Status(Substitute("Kerberos could not set KRB5_KTNAME: $0",
        GetStrErrMsg()));
  }

  // We want to set a custom location for the impala credential cache.
  // Usually, it's /tmp/krb5cc_xxx where xxx is the UID of the process.  This
  // is normally fine, but if you're not running impala daemons as user
  // 'impala', the kinit we perform is going to blow away credentials for the
  // current user.  Not setting this isn't technically fatal, so ignore errors.
  const path krb5_ccname_path(FLAGS_krb5_ccname);
  if (!krb5_ccname_path.is_absolute()) {
    return Status(Substitute("Bad --krb5_ccname value: $0 is not an absolute file path",
        FLAGS_krb5_ccname));
  }
  discard_result(setenv("KRB5CCNAME", FLAGS_krb5_ccname.c_str(), 1));

  // If an alternate krb5_conf location is supplied, set both KRB5_CONFIG and
  // JAVA_TOOL_OPTIONS in the environment.
  if (!FLAGS_krb5_conf.empty()) {
    // Ensure it points to a regular file
    if (!is_regular(FLAGS_krb5_conf)) {
      return Status(Substitute("Bad --krb5_conf value: The file $0 is not a "
          "regular file", FLAGS_krb5_conf));
    }

    // Overwrite KRB5_CONFIG
    if (setenv("KRB5_CONFIG", FLAGS_krb5_conf.c_str(), 1) < 0) {
      return Status(Substitute("Bad --krb5_conf value: Could not set "
          "KRB5_CONFIG: $0", GetStrErrMsg()));
    }

    RETURN_IF_ERROR(EnvAppend("JAVA_TOOL_OPTIONS", "java.security.krb5.conf",
        FLAGS_krb5_conf));

    LOG(INFO) << "Using custom Kerberos configuration file at "
              << FLAGS_krb5_conf;
  }

  // Set kerberos debugging, if applicable.  Errors are non-fatal.
  if (!FLAGS_krb5_debug_file.empty()) {
    bool krb5_debug_fail = false;
    if (setenv("KRB5_TRACE", FLAGS_krb5_debug_file.c_str(), 1) < 0) {
      LOG(WARNING) << "Failed to set KRB5_TRACE; --krb5_debuf_file not enabled for "
          "back-end code";
      krb5_debug_fail = true;
    }
    if (!EnvAppend("JAVA_TOOL_OPTIONS", "sun.security.krb5.debug", "true").ok()) {
      LOG(WARNING) << "Failed to set JAVA_TOOL_OPTIONS; --krb5_debuf_file not enabled "
          "for front-end code";
      krb5_debug_fail = true;
    }
    if (!krb5_debug_fail) {
      LOG(INFO) << "Kerberos debugging is enabled; kerberos messages written to "
                << FLAGS_krb5_debug_file;
    }
  }
  return Status::OK();
}

Status SecureAuthProvider::Start() {
  // True for kerberos internal use
  if (needs_kinit_) {
    DCHECK(is_internal_);
    DCHECK(!principal_.empty());
    // IMPALA-8154: Disable any Kerberos auth_to_local mappings.
    FLAGS_use_system_auth_to_local = false;
    // Starts a thread that periodically does a 'kinit'. The thread lives as long as the
    // process does.
    KUDU_RETURN_IF_ERROR(kudu::security::InitKerberosForServer(principal_, keytab_file_,
        FLAGS_krb5_ccname, false), "Could not init kerberos");
    LOG(INFO) << "Kerberos ticket granted to " << principal_;
  }

  if (has_ldap_) {
    DCHECK(!is_internal_);
    if (!FLAGS_ldap_ca_certificate.empty()) {
      int set_rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE,
          FLAGS_ldap_ca_certificate.c_str());
      if (set_rc != LDAP_SUCCESS) {
        return Status(Substitute("Could not set location of LDAP server cert: $0",
            ldap_err2string(set_rc)));
      }
    } else {
      // A warning was already logged...
      int val = LDAP_OPT_X_TLS_ALLOW;
      int set_rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT,
          reinterpret_cast<void*>(&val));
      if (set_rc != LDAP_SUCCESS) {
        return Status(Substitute(
            "Could not disable certificate requirement for LDAP server: $0",
            ldap_err2string(set_rc)));
      }
    }

    if (hostname_.empty()) {
      RETURN_IF_ERROR(GetHostname(&hostname_));
    }
  }

  return Status::OK();
}

Status SecureAuthProvider::GetServerTransportFactory(
    ThriftServer::TransportType underlying_transport_type, const std::string& server_name,
    MetricGroup* metrics, boost::shared_ptr<TTransportFactory>* factory) {
  DCHECK(!principal_.empty() || has_ldap_);

  if (underlying_transport_type == ThriftServer::HTTP) {
    bool has_kerberos = !principal_.empty();
    bool use_cookies = FLAGS_max_cookie_lifetime_s > 0;
    factory->reset(new THttpServerTransportFactory(
        server_name, metrics, has_ldap_, has_kerberos, use_cookies));
    return Status::OK();
  }

  DCHECK(underlying_transport_type == ThriftServer::BINARY);
  // This is the heart of the link between this file and thrift.  Here we
  // associate a Sasl mechanism with our callbacks.
  try {
    map<string, string> sasl_props; // Empty; unused by Thrift
    TSaslServerTransport::Factory* sst_factory = NULL;
    factory->reset(sst_factory = new TSaslServerTransport::Factory());

    if(!principal_.empty()) {
      // Tell it about Kerberos:
      sst_factory->addServerDefinition(KERBEROS_MECHANISM, service_name_,
          hostname_, realm_, 0, sasl_props,
          is_internal_ ? KERB_INT_CALLBACKS : KERB_EXT_CALLBACKS);
    }

    if (has_ldap_) {
      // Tell it about LDAP:
      sst_factory->addServerDefinition(PLAIN_MECHANISM, "LDAP", hostname_,
          "", 0, sasl_props, LDAP_EXT_CALLBACKS);
    }

  } catch (const TException& e) {
    LOG(ERROR) << "Failed to create Sasl Server transport factory: "
               << e.what();
    return Status(e.what());
  }

  VLOG_RPC << "Made " << (is_internal_ ? "internal" : "external")
           << " server transport factory with "
           << (!principal_.empty() ? "Kerberos " : " ")
           << (has_ldap_ ? "LDAP " : " ") << "authentication";

  return Status::OK();
}

Status SecureAuthProvider::WrapClientTransport(const string& hostname,
    boost::shared_ptr<TTransport> raw_transport, const string& service_name,
    boost::shared_ptr<TTransport>* wrapped_transport) {
  boost::shared_ptr<sasl::TSasl> sasl_client;
  const map<string, string> props; // Empty; unused by thrift
  const string auth_id; // Empty; unused by thrift

  DCHECK(!has_ldap_);
  DCHECK(is_internal_);

  // Since the daemons are never LDAP clients, we go straight to Kerberos
  try {
    const string& service = service_name.empty() ? service_name_ : service_name;
    sasl_client.reset(new sasl::TSaslClient(KERBEROS_MECHANISM, auth_id,
        service, hostname, props, KERB_INT_CALLBACKS.data()));
  } catch (sasl::SaslClientImplException& e) {
    LOG(ERROR) << "Failed to create a GSSAPI/SASL client: " << e.what();
    return Status(e.what());
  }
  wrapped_transport->reset(new TSaslClientTransport(sasl_client, raw_transport));

  // This function is called immediately prior to sasl_client_start(), and so
  // can be used to log an "I'm beginning authentication for this principal"
  // message.  Unfortunately, there are no hooks for us at this level to say
  // that we successfully authenticated as a client.
  VLOG_RPC << "Initiating client connection using principal " << principal_;

  return Status::OK();
}

void SecureAuthProvider::SetupConnectionContext(
    const boost::shared_ptr<ThriftServer::ConnectionContext>& connection_ptr,
    ThriftServer::TransportType underlying_transport_type, TTransport* input_transport,
    TTransport* output_transport) {
  TSocket* socket = nullptr;
  switch (underlying_transport_type) {
    case ThriftServer::BINARY: {
      TBufferedTransport* buffered_transport =
          down_cast<TBufferedTransport*>(input_transport);
      TSaslServerTransport* sasl_transport = down_cast<TSaslServerTransport*>(
          buffered_transport->getUnderlyingTransport().get());
      socket = down_cast<TSocket*>(sasl_transport->getUnderlyingTransport().get());
      // Get the username from the transport.
      connection_ptr->username = sasl_transport->getUsername();
      break;
    }
    case ThriftServer::HTTP: {
      THttpServer* http_input_transport = down_cast<THttpServer*>(input_transport);
      THttpServer* http_output_transport = down_cast<THttpServer*>(output_transport);
      THttpServer::HttpCallbacks callbacks;
      callbacks.path_fn = std::bind(
          HttpPathFn, connection_ptr.get(), std::placeholders::_1, std::placeholders::_2);
      callbacks.return_headers_fn = std::bind(ReturnHeaders, connection_ptr.get());
      callbacks.cookie_auth_fn =
          std::bind(CookieAuth, connection_ptr.get(), hash_, std::placeholders::_1);
      if (has_ldap_) {
        callbacks.basic_auth_fn =
            std::bind(BasicAuth, connection_ptr.get(), hash_, std::placeholders::_1);
      }
      if (!principal_.empty()) {
        callbacks.negotiate_auth_fn = std::bind(NegotiateAuth, connection_ptr.get(),
            hash_, std::placeholders::_1, std::placeholders::_2);
      }
      http_input_transport->setCallbacks(callbacks);
      http_output_transport->setCallbacks(callbacks);
      socket = down_cast<TSocket*>(http_input_transport->getUnderlyingTransport().get());
      break;
    }
    default:
      LOG(FATAL) << Substitute("Bad transport type: $0", underlying_transport_type);
  }
  connection_ptr->network_address =
      MakeNetworkAddress(socket->getPeerAddress(), socket->getPeerPort());
}

Status NoAuthProvider::GetServerTransportFactory(
    ThriftServer::TransportType underlying_transport_type, const std::string& server_name,
    MetricGroup* metrics, boost::shared_ptr<TTransportFactory>* factory) {
  // No Sasl - yawn.  Here, have a regular old buffered transport.
  switch (underlying_transport_type) {
    case ThriftServer::BINARY:
      factory->reset(new ThriftServer::BufferedTransportFactory());
      break;
    case ThriftServer::HTTP:
      factory->reset(new THttpServerTransportFactory());
      break;
    default:
      LOG(FATAL) << Substitute("Bad transport type: $0", underlying_transport_type);
  }
  return Status::OK();
}

Status NoAuthProvider::WrapClientTransport(const string& hostname,
    boost::shared_ptr<TTransport> raw_transport, const string& dummy_service,
    boost::shared_ptr<TTransport>* wrapped_transport) {
  // No Sasl - yawn.  Don't do any transport wrapping for clients.
  *wrapped_transport = raw_transport;
  return Status::OK();
}

void NoAuthProvider::SetupConnectionContext(
    const boost::shared_ptr<ThriftServer::ConnectionContext>& connection_ptr,
    ThriftServer::TransportType underlying_transport_type, TTransport* input_transport,
    TTransport* output_transport) {
  connection_ptr->username = "";
  TSocket* socket = nullptr;
  switch (underlying_transport_type) {
    case ThriftServer::BINARY: {
      TBufferedTransport* buffered_transport =
          down_cast<TBufferedTransport*>(input_transport);
      socket = down_cast<TSocket*>(buffered_transport->getUnderlyingTransport().get());
      break;
    }
    case ThriftServer::HTTP: {
      THttpServer* http_input_transport = down_cast<THttpServer*>(input_transport);
      THttpServer* http_output_transport = down_cast<THttpServer*>(input_transport);
      THttpServer::HttpCallbacks callbacks;
      // Even though there's no security, we set up some callbacks, eg. to allow
      // impersonation over unsecured connections for testing purposes.
      callbacks.path_fn = std::bind(
          HttpPathFn, connection_ptr.get(), std::placeholders::_1, std::placeholders::_2);
      callbacks.return_headers_fn = std::bind(ReturnHeaders, connection_ptr.get());
      http_input_transport->setCallbacks(callbacks);
      http_output_transport->setCallbacks(callbacks);
      socket = down_cast<TSocket*>(http_input_transport->getUnderlyingTransport().get());
      break;
    }
    default:
      LOG(FATAL) << Substitute("Bad transport type: $0", underlying_transport_type);
  }
  connection_ptr->network_address =
      MakeNetworkAddress(socket->getPeerAddress(), socket->getPeerPort());
}

Status AuthManager::Init() {
  ssl_socket_factory_.reset(new TSSLSocketFactory(TLSv1_0));

  bool use_ldap = false;
  const string excl_msg = "--$0 and --$1 are mutually exclusive "
      "and should not be set together";

  // Get all of the flag validation out of the way
  if (FLAGS_enable_ldap_auth) {
    use_ldap = true;

    if (!FLAGS_ldap_domain.empty()) {
      if (!FLAGS_ldap_baseDN.empty()) {
        return Status(Substitute(excl_msg, "ldap_domain", "ldap_baseDN"));
      }
      if (!FLAGS_ldap_bind_pattern.empty()) {
        return Status(Substitute(excl_msg, "ldap_domain", "ldap_bind_pattern"));
      }
    } else if (!FLAGS_ldap_baseDN.empty()) {
      if (!FLAGS_ldap_bind_pattern.empty()) {
        return Status(Substitute(excl_msg, "ldap_baseDN", "ldap_bind_pattern"));
      }
    }

    if (FLAGS_ldap_uri.empty()) {
      return Status("--ldap_uri must be supplied when --ldap_enable_auth is set");
    }

    if ((FLAGS_ldap_uri.find(LDAP_URI_PREFIX) != 0) &&
        (FLAGS_ldap_uri.find(LDAPS_URI_PREFIX) != 0)) {
      return Status(Substitute("--ldap_uri must start with either $0 or $1",
              LDAP_URI_PREFIX, LDAPS_URI_PREFIX ));
    }

    LOG(INFO) << "Using LDAP authentication with server " << FLAGS_ldap_uri;

    if (!FLAGS_ldap_tls && (FLAGS_ldap_uri.find(LDAPS_URI_PREFIX) != 0)) {
      if (FLAGS_ldap_passwords_in_clear_ok) {
        LOG(WARNING) << "LDAP authentication is being used, but without TLS. "
                     << "ALL PASSWORDS WILL GO OVER THE NETWORK IN THE CLEAR.";
      } else {
        return Status("LDAP authentication specified, but without TLS. "
                      "Passwords would go over the network in the clear. "
                      "Enable TLS with --ldap_tls or use an ldaps:// URI. "
                      "To override this is non-production environments, "
                      "specify --ldap_passwords_in_clear_ok");
      }
    } else if (FLAGS_ldap_ca_certificate.empty()) {
      LOG(WARNING) << "LDAP authentication is being used with TLS, but without "
                   << "an --ldap_ca_certificate file, the identity of the LDAP "
                   << "server cannot be verified.  Network communication (and "
                   << "hence passwords) could be intercepted by a "
                   << "man-in-the-middle attack";
    }
  }

  if (FLAGS_principal.empty() && !FLAGS_be_principal.empty()) {
    return Status("A back end principal (--be_principal) was supplied without "
        "also supplying a regular principal (--principal). Either --principal "
        "must be supplied alone, in which case it applies to all communication, "
        "or --principal and --be_principal must be supplied together, in which "
        "case --principal is used in external communication and --be_principal "
        "is used in internal (back-end) communication.");
  }

  // When acting as a client, or as a server on internal connections:
  string kerberos_internal_principal;
  // When acting as a server on external connections:
  string kerberos_external_principal;

  bool use_kerberos = IsKerberosEnabled();
  if (use_kerberos) {
    RETURN_IF_ERROR(GetInternalKerberosPrincipal(&kerberos_internal_principal));
    RETURN_IF_ERROR(GetExternalKerberosPrincipal(&kerberos_external_principal));
    DCHECK(!kerberos_internal_principal.empty());
    DCHECK(!kerberos_external_principal.empty());

    RETURN_IF_ERROR(InitKerberosEnv());
  }

  // This is written from the perspective of the daemons - thus "internal"
  // means "I am used for communication with other daemons, both as a client
  // and as a server".  "External" means that "I am used when being a server
  // for clients that are external - that is, they aren't daemons - like the
  // impala shell, odbc, jdbc, etc.
  //
  // Flags     | Internal | External
  // --------- | -------- | --------
  // None      | NoAuth   | NoAuth
  // LDAP only | NoAuth   | Sasl(ldap)
  // Kerb only | Sasl(be) | Sasl(fe)
  // Both      | Sasl(be) | Sasl(fe+ldap)

  // Set up the internal auth provider as per above.  Since there's no LDAP on
  // the client side, this is just a check for the "back end" kerberos
  // principal.
  if (use_kerberos) {
    SecureAuthProvider* sap = NULL;
    internal_auth_provider_.reset(sap = new SecureAuthProvider(true));
    RETURN_IF_ERROR(sap->InitKerberos(kerberos_internal_principal,
        FLAGS_keytab_file));
    LOG(INFO) << "Internal communication is authenticated with Kerberos";
  } else {
    internal_auth_provider_.reset(new NoAuthProvider());
    LOG(INFO) << "Internal communication is not authenticated";
  }
  RETURN_IF_ERROR(internal_auth_provider_->Start());

  // Set up the external auth provider as per above.  Either a "front end"
  // principal or ldap tells us to use a SecureAuthProvider, and we fill in
  // details from there.
  if (use_ldap || use_kerberos) {
    SecureAuthProvider* sap = NULL;
    external_auth_provider_.reset(sap = new SecureAuthProvider(false));
    if (use_kerberos) {
      RETURN_IF_ERROR(sap->InitKerberos(kerberos_external_principal,
          FLAGS_keytab_file));
      LOG(INFO) << "External communication is authenticated with Kerberos";
    }
    if (use_ldap) {
      sap->InitLdap();
      LOG(INFO) << "External communication is authenticated with LDAP";
    }
  } else {
    external_auth_provider_.reset(new NoAuthProvider());
    LOG(INFO) << "External communication is not authenticated";
  }
  RETURN_IF_ERROR(external_auth_provider_->Start());

  return Status::OK();
}

AuthProvider* AuthManager::GetExternalAuthProvider() {
  DCHECK(external_auth_provider_.get() != NULL);
  return external_auth_provider_.get();
}

AuthProvider* AuthManager::GetInternalAuthProvider() {
  DCHECK(internal_auth_provider_.get() != NULL);
  return internal_auth_provider_.get();
}

}
