void Krb5CredentialsCacheManager::writeOutCache(size_t limit) {
  auto cc_mem = getCache();
  if (cc_mem == nullptr) {
    throw std::runtime_error("Trying to persist an empty cache");
  }

  // Get a default file cache and empty it out
  Krb5CCache file_cache = Krb5CCache::makeDefault(ctx_.get());
  Krb5Principal client = cc_mem->getClientPrincipal();
  krb5_error_code code = krb5_cc_initialize(
    ctx_.get(), file_cache.get(), client.get());
  raiseIf(code, "Failed initializing file credentials cache");

  // Put 'limit' number of most frequently used credentials into the
  // top_services set.
  vector<pair<string, uint64_t>> count_vector;
  ReadLock readLock(&serviceCountLock_);
  for (auto& element : serviceCountMap_) {
    count_vector.push_back(pair<string, uint64_t>(
      element.first, element.second->getCount()));
  }
  readLock.reset();
  sort(count_vector.begin(), count_vector.end(), serviceCountCompare);

  std::set<string> top_services;
  int count = 0;
  for (auto& element : count_vector) {
    if (count >= limit) {
      break;
    }
    top_services.insert(element.first);
    count++;
  }

  // Iterate through the cc
  for (auto it = cc_mem->begin(true); it != cc_mem->end(); ++it) {
    krb5_principal borrowed_server = it->server;
    Krb5Principal server(ctx_.get(), std::move(borrowed_server));
    const string princ_string = folly::to<string>(server);
    SCOPE_EXIT { server.release(); };  // give back borrowed_server
    // Always persist config and tgt principals. And only persist
    // top 'limit' services.
    if (!it.isConfigEntry() && !server.isTgt() &&
        top_services.count(princ_string) == 0) {
      continue;
    }

    // Store the cred into a file
    code = krb5_cc_store_cred(ctx_.get(), file_cache.get(), &(*it));
    // Erase from top_services struct so we don't persist the same
    // principal more than once.
    top_services.erase(princ_string);
    raiseIf(code, "Failed storing a credential into a file");
  }
}
Krb5Keytab::Krb5Keytab(krb5_context context, const std::string& name)
    : context_(context)
    , keytab_(nullptr) {
  if (name.empty()) {
    krb5_error_code code = krb5_kt_default(context, &keytab_);
    raiseIf(context, code, "getting default keytab");
  } else {
    krb5_error_code code = krb5_kt_resolve(context, name.c_str(), &keytab_);
    raiseIf(context, code, folly::to<std::string>(
      "failed to open keytab: ", name));
  }
}
void Krb5CCache::storeCred(const krb5_creds& creds) {
  krb5_context ctx = context_.get();
  // The krb5 impl doesn't modify creds.
  krb5_error_code code = krb5_cc_store_cred(
    ctx, ccache_, const_cast<krb5_creds*>(&creds));
  raiseIf(ctx, code, "store cred to ccache");
}
Krb5Principal Krb5CCache::getClientPrincipal() const {
  krb5_principal client;
  krb5_context ctx = context_.get();
  krb5_error_code code = krb5_cc_get_principal(ctx, ccache_, &client);
  raiseIf(ctx, code, "getting client from ccache");
  return Krb5Principal(ctx, std::move(client));
}
Example #5
0
void
setupInterface(nvlist_t *data)
{
    char *iface, *gateway, *netmask, *ip;
    boolean_t primary;
    int ret;

    ret = nvlist_lookup_string(data, "interface", &iface);
    if (ret == 0) {
        plumbIf(iface);

        ret = nvlist_lookup_string(data, "ip", &ip);
        if (ret == 0) {
            ret = nvlist_lookup_string(data, "netmask", &netmask);
            if (ret == 0) {
                if (raiseIf(iface, ip, netmask) != 0) {
                    fatal(ERR_RAISE_IF, "Error bringing up interface %s",
                        iface);
                }
            }
            ret = nvlist_lookup_boolean_value(data, "primary", &primary);
            if ((ret == 0) && (primary == B_TRUE)) {
                ret = nvlist_lookup_string(data, "gateway", &gateway);
                if (ret == 0) {
                    (void) addRoute(iface, gateway, "0.0.0.0", 0);
                }
            }
        }
    }
}
 State(Krb5Keytab* kt)
   : kt_(kt) {
   CHECK(kt);
   krb5_error_code code =
     krb5_kt_start_seq_get(kt_->getContext(), kt_->get(), &cursor_);
   raiseIf(kt_->getContext(), code, "reading keytab " + kt_->getName());
   memset(&ktentry_, 0, sizeof(ktentry_));
 }
Krb5CCache Krb5CCache::makeDefault() {
  krb5_ccache ccache;
  Krb5Context context(true);
  krb5_context ctx = context.get();
  krb5_error_code code = krb5_cc_default(ctx, &ccache);
  raiseIf(ctx, code, "getting default ccache");
  return Krb5CCache(ccache);
}
std::string Krb5Keytab::getDefaultKeytabName(krb5_context context) {
  char name[kKeytabNameMaxLength];
  krb5_error_code code = krb5_kt_default_name(context,
                                              name,
                                              sizeof(name));
  raiseIf(context, code, "getting default keytab name");
  return name;
}
std::string Krb5Keytab::getName() const {
  char name[kKeytabNameMaxLength];
  krb5_error_code code = krb5_kt_get_name(context_,
                                          keytab_,
                                          name,
                                          sizeof(name));
  raiseIf(context_, code, "getting keytab name");
  return name;
}
Krb5CCache Krb5CCache::makeResolve(const std::string& name) {
  krb5_ccache ccache;
  Krb5Context context(true);
  krb5_context ctx = context.get();
  krb5_error_code code = krb5_cc_resolve(ctx, name.c_str(), &ccache);
  raiseIf(ctx, code, folly::to<std::string>(
    "failed to resolve ccache: ", name));
  return Krb5CCache(ccache);
}
Krb5CCache Krb5CCache::makeNewUnique(const std::string& type) {
  krb5_ccache ccache;
  Krb5Context context(true);
  krb5_context ctx = context.get();
  krb5_error_code code = krb5_cc_new_unique(
    ctx, type.c_str(), nullptr, &ccache);
  raiseIf(ctx, code, folly::to<std::string>(
    "failed to get new ccache with type: ", type));
  return Krb5CCache(ccache);
}
Krb5Credentials Krb5Keytab::getInitCreds(
  krb5_principal princ, krb5_get_init_creds_opt* opts) {

  krb5_creds creds;
  krb5_error_code code = krb5_get_init_creds_keytab(
    context_, &creds, princ, keytab_, 0 /* starttime */,
    nullptr /* initial sname */, opts);
  raiseIf(context_, code, "getting credentials from keytab");
  return Krb5Credentials(std::move(creds));
}
 State(const Krb5CCache* cc, bool include_config_entries)
   : cc_(cc)
   , include_config_entries_(include_config_entries)
   , context_(true) {
   CHECK(cc);
   krb5_context ctx = context_.get();
   krb5_error_code code =
     krb5_cc_start_seq_get(ctx, cc_->get(), &cursor_);
   raiseIf(ctx, code, "reading credentials cache");
   memset(&creds_, 0, sizeof(creds_));
 }
std::unique_ptr<Krb5CCache> Krb5CredentialsCacheManager::readInCache() {
  auto mem = folly::make_unique<Krb5CCache>(
    Krb5CCache::makeNewUnique(ctx_.get(), "MEMORY"));
  // Get the default local cache
  Krb5CCache file_cache = Krb5CCache::makeDefault(ctx_.get());
  Krb5Principal client = file_cache.getClientPrincipal();

  // Copy the cache into memory
  krb5_error_code code = krb5_cc_initialize(
    ctx_.get(), mem->get(), client.get());
  raiseIf(code, "initializing memory ccache");
  code = krb5_cc_copy_creds(ctx_.get(), file_cache.get(), mem->get());
  raiseIf(code, "copying to memory cache");

  auto service_list = mem->getServicePrincipalList();
  for (auto& service : service_list)  {
    incUsedService(folly::to<string>(service));
  }

  return mem;
}
 bool next() {
   krb5_free_keytab_entry_contents(kt_->getContext(), &ktentry_);
   memset(&ktentry_, 0, sizeof(ktentry_));
   krb5_error_code code =
     krb5_kt_next_entry(kt_->getContext(), kt_->get(), &ktentry_, &cursor_);
   if (code == KRB5_KT_END) {
     return false;
   } else {
     raiseIf(kt_->getContext(), code, "reading next credential");
   }
   return true;
 }
Krb5Credentials Krb5CCache::retrieveCred(
  const krb5_creds& match_creds, krb5_flags match_flags) {

  krb5_creds matched;
  krb5_context ctx = context_.get();
  // The krb5 impl doesn't modify match_creds.
  krb5_error_code code = krb5_cc_retrieve_cred(
    ctx, ccache_, match_flags, const_cast<krb5_creds*>(&match_creds),
    &matched);
  raiseIf(ctx, code, "retrieve cred");

  return Krb5Credentials(std::move(matched));
}
 bool next_any() {
   krb5_context ctx = context_.get();
   krb5_free_cred_contents(ctx, &creds_);
   memset(&creds_, 0, sizeof(creds_));
   krb5_error_code code =
     krb5_cc_next_cred(ctx, cc_->get(), &cursor_, &creds_);
   if (code == KRB5_CC_END) {
     return false;
   } else {
     raiseIf(ctx, code, "reading next credential");
   }
   return true;
 }
Krb5Credentials Krb5CCache::getCredentials(
  const krb5_creds& in_creds, krb5_flags options) {

  krb5_creds* out_creds;
  krb5_context ctx = context_.get();
  // The krb5 impl doesn't modify in_creds.
  krb5_error_code code = krb5_get_credentials(
    ctx, options, ccache_, const_cast<krb5_creds*>(&in_creds),
    &out_creds);
  raiseIf(ctx, code, "get credentials");
  SCOPE_EXIT { krb5_free_creds(ctx, out_creds); };

  return Krb5Credentials(std::move(*out_creds));
}
Example #19
0
void
setupNetworking()
{
    openIpadmHandle();

    plumbIf("lo0");
    (void) raiseIf("lo0", "127.0.0.1", "255.0.0.0");

    setupInterfaces();

    /*
     * Configure any additional static routes from NAPI networks:
     */
    setupStaticRoutes();

    closeIpadmHandle();
}
 ~State() {
   krb5_context ctx = context_.get();
   krb5_free_cred_contents(ctx, &creds_);
   krb5_error_code code = krb5_cc_end_seq_get(ctx, cc_->get(), &cursor_);
   raiseIf(ctx, code, "ending read of credentials cache");
 }
Krb5Principal::Krb5Principal(krb5_context context, const std::string& name)
    : context_(context)
    , principal_(nullptr) {
  krb5_error_code code = krb5_parse_name(context, name.c_str(), &principal_);
  raiseIf(context, code, folly::to<std::string>("parsing principal ", name));
}
void Krb5CCache::initialize(krb5_principal cprinc) {
  krb5_context ctx = context_.get();
  krb5_error_code code = krb5_cc_initialize(ctx, ccache_, cprinc);
  raiseIf(ctx, code, "initializing ccache");
}
Krb5InitCredsOpt::Krb5InitCredsOpt(krb5_context context)
    : context_(context)
    , options_(nullptr) {
  krb5_error_code code = krb5_get_init_creds_opt_alloc(context, &options_);
  raiseIf(context, code, "getting default options");
}
 ~State() {
   krb5_free_keytab_entry_contents(kt_->getContext(), &ktentry_);
   krb5_error_code code =
     krb5_kt_end_seq_get(kt_->getContext(), kt_->get(), &cursor_);
   raiseIf(kt_->getContext(), code, "ending read of keytab " + kt_->getName());
 }