bool AclData::lookupMatchRule()

in src/qpid/acl/AclData.cpp [159:360]


bool AclData::lookupMatchRule(
    const ruleSetItr&                rsItr,
    const std::string&               id,
    const std::string&               name,
    const std::map<Property, std::string>* params,
    AclResult&                       aclresult)
{
    QPID_LOG(debug, "ACL: checking rule " <<  rsItr->toString());

    bool match = true;
    bool limitChecked = true;

    // Iterate this rule's properties. A 'match' is true when
    // all of the rule's properties are found to be satisfied
    // in the lookup param list. The lookup may specify things
    // (they usually do) that are not in the rule properties but
    // these things don't interfere with the rule match.

    for (specPropertyMapItr rulePropMapItr  = rsItr->props.begin();
                           (rulePropMapItr != rsItr->props.end()) && match;
                            rulePropMapItr++) {
        // The rule property map's NAME property is given in
        // the calling args and not in the param map.
        if (rulePropMapItr->first == acl::SPECPROP_NAME)
        {
            // substitute user name into object name
            bool result;
            if (rsItr->ruleHasUserSub[PROP_NAME]) {
                std::string sName(rulePropMapItr->second);
                substituteUserId(sName, id);
                result = matchProp(sName, name);
            } else {
                result = matchProp(rulePropMapItr->second, name);
            }

            if (result) {
                QPID_LOG(debug, "ACL: lookup name '" << name
                            << "' matched with rule name '"
                            << rulePropMapItr->second << "'");
            } else {
                match = false;
                QPID_LOG(debug, "ACL: lookup name '" << name
                            << "' didn't match with rule name '"
                            << rulePropMapItr->second << "'");
            }
        } else {
            if (params) {
                // The rule's property map non-NAME properties
                //  found in the lookup's params list.
                // In some cases the param's index is not the same
                //  as rule's index.
                propertyMapItr lookupParamItr;
                switch (rulePropMapItr->first) {
                case acl::SPECPROP_MAXPAGESLOWERLIMIT:
                case acl::SPECPROP_MAXPAGESUPPERLIMIT:
                    lookupParamItr = params->find(PROP_MAXPAGES);
                    break;

                case acl::SPECPROP_MAXPAGEFACTORLOWERLIMIT:
                case acl::SPECPROP_MAXPAGEFACTORUPPERLIMIT:
                    lookupParamItr = params->find(PROP_MAXPAGEFACTOR);
                    break;

                case acl::SPECPROP_MAXQUEUECOUNTUPPERLIMIT:
                case acl::SPECPROP_MAXQUEUECOUNTLOWERLIMIT:
                    lookupParamItr = params->find(PROP_MAXQUEUECOUNT);
                    break;

                case acl::SPECPROP_MAXQUEUESIZEUPPERLIMIT:
                case acl::SPECPROP_MAXQUEUESIZELOWERLIMIT:
                    lookupParamItr = params->find(PROP_MAXQUEUESIZE);
                    break;

                case acl::SPECPROP_MAXFILECOUNTUPPERLIMIT:
                case acl::SPECPROP_MAXFILECOUNTLOWERLIMIT:
                    lookupParamItr = params->find(PROP_MAXFILECOUNT);
                    break;

                case acl::SPECPROP_MAXFILESIZEUPPERLIMIT:
                case acl::SPECPROP_MAXFILESIZELOWERLIMIT:
                    lookupParamItr = params->find(PROP_MAXFILESIZE);
                    break;

                default:
                    lookupParamItr = params->find((Property)rulePropMapItr->first);
                    break;
                };

                if (lookupParamItr == params->end()) {
                    // Now the rule has a specified property
                    // that does not exist in the caller's
                    // lookup params list.
                    // This rule does not match.
                    match = false;
                    QPID_LOG(debug, "ACL: lookup parameter map doesn't contain the rule property '"
                                << AclHelper::getPropertyStr(rulePropMapItr->first) << "'");
                } else {
                    // Now account for the business of rules
                    // whose property indexes are mismatched.
                    switch (rulePropMapItr->first) {
                    case acl::SPECPROP_MAXQUEUECOUNTUPPERLIMIT:
                    case acl::SPECPROP_MAXQUEUESIZEUPPERLIMIT:
                    case acl::SPECPROP_MAXFILECOUNTUPPERLIMIT:
                    case acl::SPECPROP_MAXFILESIZEUPPERLIMIT:
                    case acl::SPECPROP_MAXPAGESUPPERLIMIT:
                    case acl::SPECPROP_MAXPAGEFACTORUPPERLIMIT:
                        limitChecked &=
                            compareInt(
                                rulePropMapItr->first,
                                boost::lexical_cast<std::string>(rulePropMapItr->second),
                                boost::lexical_cast<std::string>(lookupParamItr->second),
                                true);
                        break;

                    case acl::SPECPROP_MAXQUEUECOUNTLOWERLIMIT:
                    case acl::SPECPROP_MAXQUEUESIZELOWERLIMIT:
                    case acl::SPECPROP_MAXFILECOUNTLOWERLIMIT:
                    case acl::SPECPROP_MAXFILESIZELOWERLIMIT:
                    case acl::SPECPROP_MAXPAGESLOWERLIMIT:
                    case acl::SPECPROP_MAXPAGEFACTORLOWERLIMIT:
                        limitChecked &=
                            compareInt(
                                rulePropMapItr->first,
                                boost::lexical_cast<std::string>(rulePropMapItr->second),
                                boost::lexical_cast<std::string>(lookupParamItr->second),
                                false);
                        break;

                    default:
                        bool result;
                        if ((SPECPROP_ALTERNATE  == rulePropMapItr->first && rsItr->ruleHasUserSub[PROP_ALTERNATE])  ||
                            (SPECPROP_QUEUENAME  == rulePropMapItr->first && rsItr->ruleHasUserSub[PROP_QUEUENAME])) {
                            // These properties are allowed to have username substitution
                            std::string sName(rulePropMapItr->second);
                            substituteUserId(sName, id);
                            result = matchProp(sName, lookupParamItr->second);
                        } else if (SPECPROP_ROUTINGKEY == rulePropMapItr->first) {
                            // Routing key is allowed to have username substitution
                            // and it gets topic exchange matching
                            if (rsItr->ruleHasUserSub[PROP_ROUTINGKEY]) {
                                std::string sKey(lookupParamItr->second);
                                substituteKeywords(sKey, id);
                                result = rsItr->matchRoutingKey(sKey);
                            } else {
                                result = rsItr->matchRoutingKey(lookupParamItr->second);
                            }
                        } else {
                            // Rules without substitution
                            result = matchProp(rulePropMapItr->second, lookupParamItr->second);
                        }

                        if (result) {
                            QPID_LOG(debug, "ACL: the pair("
                                     << AclHelper::getPropertyStr(lookupParamItr->first)
                                     << "," << lookupParamItr->second
                                     << ") given in lookup matched the pair("
                                     << AclHelper::getPropertyStr(rulePropMapItr->first) << ","
                                     << rulePropMapItr->second
                                     << ") given in the rule");
                        } else {
                            match = false;
                            QPID_LOG(debug, "ACL: the pair("
                                     << AclHelper::getPropertyStr(lookupParamItr->first)
                                     << "," << lookupParamItr->second
                                     << ") given in lookup doesn't match the pair("
                                     << AclHelper::getPropertyStr(rulePropMapItr->first)
                                     << "," << rulePropMapItr->second
                                     << ") given in the rule");
                        }
                        break;
                    };
                }
            } else {
                // params don't exist.
            }
        }
    }
    if (match) {
        aclresult = rsItr->ruleMode;
        if (!limitChecked) {
            // Now a lookup matched all rule properties but one
            //  of the numeric limit checks has failed.
            // Demote allow rules to corresponding deny rules.
            switch (aclresult) {
            case acl::ALLOW:
                aclresult = acl::DENY;
                break;
            case acl::ALLOWLOG:
                aclresult = acl::DENYLOG;
                break;
            default:
                break;
            };
        }
        QPID_LOG(debug,"ACL: Successful match, the decision is:"
                 << AclHelper::getAclResultStr(aclresult));
    } else {
        // This rule did not match the requested lookup and
        // does not contribute to an ACL decision.
    }
    return match;
}