Check whether or not the client is permitted specified access to a path.
488 std::vector<std::string_view> authz_list;
489 authz_list.reserve(1);
495 ParseTokenString(
"authz", env, authz_list);
496 ParseTokenString(
"access_token", env, authz_list);
498 if (Entity && !strcmp(
"ztn", Entity->
prot) && Entity->
creds &&
501 authz_list.push_back(Entity->
creds);
504 if (authz_list.empty()) {
505 return OnMissing(Entity, path, oper, env);
510 if (authz_list.size() > 10) {
511 m_log.
Log(
LogMask::Warning,
"Access",
"Request had more than 10 tokens attached; ignoring");
512 return OnMissing(Entity, path, oper, env);
516 std::vector<std::shared_ptr<XrdAccRules>> access_rules_list;
517 uint64_t now = monotonic_time();
519 for (
const auto &authz : authz_list) {
520 std::shared_ptr<XrdAccRules> access_rules;
522 std::lock_guard<std::mutex> guard(m_mutex);
523 const auto iter = m_map.find(authz);
524 if (iter != m_map.end() && !iter->second->expired()) {
525 access_rules = iter->second;
529 m_log.
Log(
LogMask::Debug,
"Access",
"Token not found in recent cache; parsing.");
531 uint64_t cache_expiry;
533 std::string username;
534 std::string token_subject;
536 std::vector<MapRule> map_rules;
537 std::vector<std::string> groups;
538 uint32_t authz_strategy;
540 if (GenerateAcls(authz, cache_expiry, rules, username, token_subject, issuer, map_rules, groups, authz_strategy, acceptable_authz)) {
541 access_rules.reset(
new XrdAccRules(now + cache_expiry, username, token_subject, issuer, map_rules, groups, authz_strategy, acceptable_authz));
542 access_rules->parse(rules);
548 m_log.
Log(
LogMask::Debug,
"Access",
"New valid token", access_rules->str().c_str());
550 }
catch (std::exception &exc) {
551 m_log.
Log(
LogMask::Warning,
"Access",
"Error generating ACLs for authorization", exc.what());
554 std::lock_guard<std::mutex> guard(m_mutex);
555 m_map[std::string(authz)] = access_rules;
557 m_log.
Log(
LogMask::Debug,
"Access",
"Cached token", access_rules->str().c_str());
559 access_rules_list.push_back(access_rules);
561 if (access_rules_list.empty()) {
562 return OnMissing(Entity, path, oper, env);
564 std::string_view path_view(path, strlen(path));
568 return OnMissing(Entity, path, oper, env);
582 for (
const auto &access_rules : access_rules_list) {
584 if (!access_rules->acceptable_authz(oper)) {
585 m_log.
Log(
LogMask::Debug,
"Access",
"Issuer is not acceptable for given operation:", access_rules->get_issuer().c_str());
590 new_secentity.
vorg =
nullptr;
591 new_secentity.
grps =
nullptr;
592 new_secentity.
role =
nullptr;
595 const auto &issuer = access_rules->get_issuer();
596 if (!issuer.empty()) {
597 new_secentity.
vorg = strdup(issuer.c_str());
599 bool group_success =
false;
600 if ((access_rules->get_authz_strategy() &
IssuerAuthz::Group) && access_rules->groups().size()) {
601 std::stringstream ss;
602 for (
const auto &grp : access_rules->groups()) {
605 const auto &groups_str = ss.str();
606 new_secentity.
grps =
static_cast<char*
>(malloc(groups_str.size() + 1));
607 if (new_secentity.
grps) {
608 memcpy(new_secentity.
grps, groups_str.c_str(), groups_str.size());
609 new_secentity.
grps[groups_str.size()] =
'\0';
611 group_success =
true;
614 std::string username;
615 bool mapping_success =
false;
616 bool scope_success =
false;
617 username = access_rules->get_username(path_view);
619 mapping_success = (access_rules->get_authz_strategy() &
IssuerAuthz::Mapping) && !username.empty();
620 scope_success = (access_rules->get_authz_strategy() &
IssuerAuthz::Capability) && access_rules->apply(oper, path_view);
622 std::stringstream ss;
623 ss <<
"Grant authorization based on scopes for operation=" << OpToName(oper) <<
", path=" << path;
627 if (!scope_success && !mapping_success && !group_success) {
628 auto returned_accs = OnMissing(&new_secentity, path, oper, env);
630 if (new_secentity.
vorg !=
nullptr) free(new_secentity.
vorg);
631 if (new_secentity.
grps !=
nullptr) free(new_secentity.
grps);
632 if (new_secentity.
role !=
nullptr) free(new_secentity.
role);
634 return returned_accs;
638 if (scope_success && username.empty()) {
639 username = access_rules->get_default_username();
644 if (scope_success || mapping_success) {
646 Entity->
eaAPI->
Add(
"request.name", username,
true);
647 new_secentity.
eaAPI->
Add(
"request.name", username,
true);
656 const auto &token_subject = access_rules->get_token_subject();
657 if (!token_subject.empty()) {
658 Entity->
eaAPI->
Add(
"token.subject", token_subject,
true);
667 if (Entity->
secMon && scope_success && returned_op &&
Mon_isIO(oper))
668 Mon_Report(new_secentity, token_subject, username);
671 if (new_secentity.
vorg !=
nullptr) free(new_secentity.
vorg);
672 if (new_secentity.
grps !=
nullptr) free(new_secentity.
grps);
673 if (new_secentity.
role !=
nullptr) free(new_secentity.
role);
678 return OnMissing(Entity, path, oper, env);
bool AuthorizesRequiredIssuers(Access_Operation client_oper, const std::string_view &path, const std::vector< std::pair< std::unique_ptr< SubpathMatch >, std::string >> &required_issuers, const std::vector< std::shared_ptr< XrdAccRules >> &access_rules_list)
std::vector< std::pair< Access_Operation, std::string > > AccessRulesRaw
bool Mon_isIO(const Access_Operation oper)
void Mon_Report(const XrdSecEntity &Entity, const std::string &subject, const std::string &username)
bool Add(XrdSecAttr &attr)
char * vorg
Entity's virtual organization(s)
int credslen
Length of the 'creds' data.
XrdNetAddrInfo * addrInfo
Entity's connection details.
XrdSecEntityAttr * eaAPI
non-const API to attributes
char prot[XrdSecPROTOIDSIZE]
Auth protocol used (e.g. krb5)
char * creds
Raw entity credentials or cert.
XrdSecMonitor * secMon
If !0 security monitoring enabled.
char * grps
Entity's group name(s)
char * role
Entity's role(s)
void Log(int mask, const char *esfx, const char *text1, const char *text2=0, const char *text3=0)