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