Commit 267d436a authored by jan.koester's avatar jan.koester
Browse files

test

parent 9067bb3b
Loading
Loading
Loading
Loading
Loading
+17 −2
Changes for plugin/ad/ad.cpp: 17 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -1747,7 +1747,7 @@ std::vector<uint8_t> ActiveDirectory::handleSearchRequest(const uint8_t *content
                rc = LDAP_SIZE_LIMIT_EXCEEDED;
                return false;
            }
            LdapEntry le = renderEntry(ent, requested, typesOnly);
            LdapEntry le = renderEntry(ent, requested, typesOnly, d.dir.get());
            {
                std::string dump;
                for (auto &at : le.attributes) {
@@ -1780,7 +1780,7 @@ std::vector<uint8_t> ActiveDirectory::handleSearchRequest(const uint8_t *content
 *****************************************************************************/
LdapEntry ActiveDirectory::renderEntry(const dsdb::Entry &ent,
                                       const std::vector<std::string> &requested,
                                       bool typesOnly) {
                                       bool typesOnly, dsdb::Directory *dir) {
    using namespace dsdb;
    LdapEntry le;
    le.dn = ent.dn.str();
@@ -1823,6 +1823,21 @@ LdapEntry ActiveDirectory::renderEntry(const dsdb::Entry &ent,
        le.attributes.push_back(std::move(a));
    }

    /* tokenGroups: constructed, only when asked for by name (as in AD) */
    if (dir && !ent.objectSid.empty()) {
        for (auto &n : named) {
            if (!iequals(n, "tokenGroups") && !iequals(n, "tokenGroupsGlobalAndUniversal"))
                continue;
            LdapAttribute a;
            a.type = "tokenGroups";
            if (!typesOnly)
                for (auto &sid : dir->tokenGroupsInSearch(ent))
                    a.values.push_back(sid.binary());
            le.attributes.push_back(std::move(a));
            break;
        }
    }

    /* objectGUID is the record UUID (a separate Entry field, not in attrs):
     * synthesize it as the 16-byte binary GUID AD clients expect -- the
     * UUID's bytes as they are (network order), see buildRootDSE(). Windows
+1 −1
Changes for plugin/ad/ad.h: 1 added line, 1 removed line.
Original line number Diff line number Diff line
@@ -372,7 +372,7 @@ namespace fenrirds {
         * attribute list (empty / "*" = all user attrs; "+" = operational;
         * "1.1" = none; secret attributes are never returned) */
        LdapEntry renderEntry(const dsdb::Entry &e, const std::vector<std::string> &requested,
                              bool typesOnly);
                              bool typesOnly, dsdb::Directory *dir = nullptr);
        LdapEntry buildRootDSE();
        /* parse a BER-encoded LDAP filter into a dsdb::Filter */
        bool parseFilter(const uint8_t *data, size_t len, dsdb::Filter &out);
+36 −0
Changes for src/dsdb/directory.cpp: 36 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -13,6 +13,42 @@ namespace dsdb {
Directory::Directory(AuthBackend &backend, const DomainMeta &meta)
    : _Backend(backend), _Meta(meta) {}

std::vector<Sid> Directory::tokenGroupsInSearch(const Entry &e) {
    std::vector<Sid> out;
    std::map<std::string, bool, CaseLess> seen;
    std::vector<std::string> work;
    auto addGroup = [&](const Entry *g) {
        if (!g || seen.count(g->dn.str()))
            return;
        seen[g->dn.str()] = true;
        if (!g->objectSid.empty())
            out.push_back(g->objectSid);
        if (auto it = g->attrs.find("memberOf"); it != g->attrs.end())
            work.insert(work.end(), it->second.begin(), it->second.end());
    };
    /* the primary group (domain SID + primaryGroupID) */
    int64_t pg = intValue(e.attrs, "primaryGroupID", 0);
    if (pg > 0 && !e.objectSid.empty()) {
        Sid psid = e.objectSid.domain().withRid(uint32_t(pg));
        auto it = _BySid.find(psid.binary());
        if (it != _BySid.end() && it->second < _Entries.size())
            addGroup(&_Entries[it->second]);
        else
            out.push_back(psid);
    }
    if (auto it = e.attrs.find("memberOf"); it != e.attrs.end())
        work.insert(work.end(), it->second.begin(), it->second.end());
    while (!work.empty()) {
        std::string cur = work.back();
        work.pop_back();
        Dn dn;
        if (seen.count(cur) || !Dn::parse(cur, dn))
            continue;
        addGroup(findByDnLocked(dn));
    }
    return out;
}

MatchContext Directory::matchContext() {
    MatchContext ctx;
    DomainMeta m = _Meta;
+4 −0
Changes for src/dsdb/directory.h: 4 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -132,6 +132,10 @@ namespace fenrirds {

            /* with _Mtx held: its callbacks look entries up unlocked */
            MatchContext matchContext();
            /* the constructed tokenGroups of a principal: the SIDs of its
             * primary group and of all groups it is in, transitively. Only
             * call from inside a search() callback (the lock is held). */
            std::vector<Sid> tokenGroupsInSearch(const Entry &e);

        private:
            void ensureFresh();