Commit 66c5facb authored by jan.koester's avatar jan.koester
Browse files

test

parent 84de7621
Loading
Loading
Loading
Loading
+59 −0
Changes for test/fakeldap.cpp: 59 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -204,6 +204,16 @@ Server::Server(std::vector<Object> objects, std::string bindDn, std::string bind
    _acceptThread = std::thread(&Server::acceptLoop, this);
}

bool Server::object(const std::string &dn, Object &out) {
    std::lock_guard<std::mutex> l(_objectsLock);
    for (const Object &o : _objects)
        if (lower(o.dn) == lower(dn)) {
            out = o;
            return true;
        }
    return false;
}

Server::~Server() {
    _stop = true;
    ::shutdown(_listen, SHUT_RDWR);
@@ -263,10 +273,59 @@ std::string Server::answer(const ldap::Message &m, bool &bound, bool &quit) {
        return message(m.id, bound ? result(ldap::BindResponse, 0)
                                   : result(ldap::BindResponse, 49, "80090308: LdapErr: invalid credentials"));
    }
    if (m.op == ldap::AddRequest || m.op == ldap::ModifyRequest) {
        uint8_t resp = m.op == ldap::AddRequest ? ldap::AddResponse : ldap::ModifyResponse;
        if (!bound) return message(m.id, result(resp, 1, "a successful bind must be completed"));
        ber::Reader r(m.body);
        std::string dn = r.next(ber::OctetString).content;
        ber::Reader list(r.next(ber::Sequence).content);
        std::lock_guard<std::mutex> l(_objectsLock);
        Object *o = nullptr;
        for (Object &x : _objects)
            if (lower(x.dn) == lower(dn)) o = &x;
        if (m.op == ldap::AddRequest) {
            if (o) return message(m.id, result(resp, 68, "entry already exists"));
            Object n{ dn, {} };
            while (!list.atEnd()) {
                ber::Reader a(list.next(ber::Sequence).content);
                std::string type = a.next(ber::OctetString).content;
                std::vector<std::string> vals;
                ber::Reader v(a.next(ber::Set).content);
                while (!v.atEnd()) vals.push_back(v.next(ber::OctetString).content);
                n.attrs.emplace_back(type, vals);
            }
            _objects.push_back(n);
            return message(m.id, result(resp, 0));
        }
        if (!o) return message(m.id, result(resp, 32, "no such object"));
        while (!list.atEnd()) {
            ber::Reader c(list.next(ber::Sequence).content);
            int op = (int)ber::toInt(c.next(ber::Enumerated));
            ber::Reader a(c.next(ber::Sequence).content);
            std::string type = a.next(ber::OctetString).content;
            std::vector<std::string> vals;
            ber::Reader v(a.next(ber::Set).content);
            while (!v.atEnd()) vals.push_back(v.next(ber::OctetString).content);
            auto it = o->attrs.begin();
            for (; it != o->attrs.end(); ++it)
                if (lower(it->first) == lower(type)) break;
            if (op == 2) {  /* replace */
                if (it != o->attrs.end()) it->second = vals;
                else o->attrs.emplace_back(type, vals);
            } else if (op == 0) {
                if (it != o->attrs.end()) it->second.insert(it->second.end(), vals.begin(), vals.end());
                else o->attrs.emplace_back(type, vals);
            } else if (it != o->attrs.end()) {
                o->attrs.erase(it);
            }
        }
        return message(m.id, result(resp, 0));
    }
    if (m.op != ldap::SearchRequest)
        return message(m.id, result(ldap::ExtendedResponse, 2, "unsupported"));
    if (!bound)
        return message(m.id, result(ldap::SearchResultDone, 1, "a successful bind must be completed"));
    std::lock_guard<std::mutex> objLock(_objectsLock);

    _searches++;
    ber::Reader r(m.body);
+3 −0
Changes for test/fakeldap.h: 3 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -56,6 +56,8 @@ public:
    int port() const { return _port; }
    /* how many searches were answered */
    int searches() const { return _searches; }
    /* the object with this DN as it is now (after adds and modifies) */
    bool object(const std::string &dn, Object &out);

private:
    void acceptLoop();
@@ -63,6 +65,7 @@ private:
    std::string answer(const adconnect::ldap::Message &m, bool &bound, bool &quit);

    std::vector<Object> _objects;
    std::mutex _objectsLock;
    std::string _bindDn, _bindPassword;
    int _listen = -1;
    int _port = 0;