Commit a84512bd authored by jan.koester's avatar jan.koester
Browse files

test

parent bd55ad58
Loading
Loading
Loading
Loading
Loading
+61 −16
Changes for src/cluster.cpp: 61 added lines, 16 removed lines.
Original line number Diff line number Diff line
@@ -60,6 +60,8 @@ namespace authdb {
    //   [16B * member_count member uuids]
    //   [4B username_len]
    //   [username_len bytes username]
    //   [4B gpo_count]
    //   [for each GPO: 16B GPOId + 1B GPORes]

    std::vector<uint8_t> SessionBlock::serialize(const SessionData &sess) {
        uuid::uuid sid, uid, did;
@@ -71,13 +73,15 @@ namespace authdb {

        // Collect members
        std::vector<uuid::uuid> members;
        // We need to iterate the session's members - since isMemberOf is the
        // public API, we'll reconstruct via the SessionData copy
        // The SessionData stores members internally, we access via serialization
        sess.getMembers(members);

        // Header: 16+16+16 + 4 + 4 = 56 bytes minimum
        // Plus member UUIDs and username
        size_t total = 48 + 4 + 4 + username_len;
        // Collect GPO results
        std::vector<std::pair<uuid::uuid, bool>> gpo_results;
        sess.getGPOResults(gpo_results);

        // Header: 16+16+16 + 4 + members*16 + 4 + username + 4 + gpos*17
        size_t total = 48 + 4 + (members.size() * 16) + 4 + username_len
                     + 4 + (gpo_results.size() * 17);

        std::vector<uint8_t> buf(total);
        size_t pos = 0;
@@ -94,11 +98,16 @@ namespace authdb {
        std::memcpy(buf.data() + pos, did.value, 16);
        pos += 16;

        // Member count = 0 for basic serialization (members stored separately)
        uint32_t mc = 0;
        // Member count and UUIDs
        uint32_t mc = static_cast<uint32_t>(members.size());
        std::memcpy(buf.data() + pos, &mc, 4);
        pos += 4;

        for (const auto &m : members) {
            std::memcpy(buf.data() + pos, m.value, 16);
            pos += 16;
        }

        // Username length
        uint32_t ul = static_cast<uint32_t>(username_len);
        std::memcpy(buf.data() + pos, &ul, 4);
@@ -107,6 +116,19 @@ namespace authdb {
        // Username
        if (username_len > 0) {
            std::memcpy(buf.data() + pos, username, username_len);
            pos += username_len;
        }

        // GPO count and results
        uint32_t gc = static_cast<uint32_t>(gpo_results.size());
        std::memcpy(buf.data() + pos, &gc, 4);
        pos += 4;

        for (const auto &gpo : gpo_results) {
            std::memcpy(buf.data() + pos, gpo.first.value, 16);
            pos += 16;
            buf[pos] = gpo.second ? 1 : 0;
            pos += 1;
        }

        return buf;
@@ -115,7 +137,8 @@ namespace authdb {
    bool SessionBlock::deserialize(const std::vector<uint8_t> &data,
                                    uuid::uuid &sid, uuid::uuid &uid, uuid::uuid &did,
                                    std::vector<uuid::uuid> &members,
                                    std::string &username) {
                                    std::string &username,
                                    std::vector<std::pair<uuid::uuid, bool>> &gpo_results) {
        if (data.size() < 56) return false;

        size_t pos = 0;
@@ -149,6 +172,25 @@ namespace authdb {

        if (pos + ul > data.size()) return false;
        username.assign(reinterpret_cast<const char*>(data.data() + pos), ul);
        pos += ul;

        // Parse GPO results (may be absent in older format)
        gpo_results.clear();
        if (pos + 4 <= data.size()) {
            uint32_t gc = 0;
            std::memcpy(&gc, data.data() + pos, 4);
            pos += 4;

            for (uint32_t i = 0; i < gc; i++) {
                if (pos + 17 > data.size()) return false;
                uuid::uuid gpoid;
                std::memcpy(gpoid.value, data.data() + pos, 16);
                pos += 16;
                bool gpores = (data[pos] != 0);
                pos += 1;
                gpo_results.emplace_back(gpoid, gpores);
            }
        }

        return true;
    }
@@ -321,14 +363,15 @@ namespace authdb {

    bool Cluster::fetchSession(const uuid::uuid &uid, const uuid::uuid &did,
                                uuid::uuid &sid, std::vector<uuid::uuid> &members,
                                std::string &username) {
                                std::string &username,
                                std::vector<std::pair<uuid::uuid, bool>> &gpo_results) {
        uint64_t sgid = sessionGroupId(uid, did);

        // Check local store first
        std::vector<uint8_t> data;
        if (store_->fetch(sgid, 0, data)) {
            uuid::uuid d_uid, d_did;
            if (SessionBlock::deserialize(data, sid, d_uid, d_did, members, username)) {
            if (SessionBlock::deserialize(data, sid, d_uid, d_did, members, username, gpo_results)) {
                return true;
            }
        }
@@ -339,7 +382,7 @@ namespace authdb {
                std::lock_guard<std::mutex> lock(client_mutex_);
                if (pclient_->fetch_from_peers(sgid, 0, data) && !data.empty()) {
                    uuid::uuid d_uid, d_did;
                    if (SessionBlock::deserialize(data, sid, d_uid, d_did, members, username)) {
                    if (SessionBlock::deserialize(data, sid, d_uid, d_did, members, username, gpo_results)) {
                        // Cache locally for next time
                        store_->store(sgid, 0, data.data(), data.size());
                        return true;
@@ -362,7 +405,8 @@ namespace authdb {
            uuid::uuid sid, d_uid, d_did;
            std::vector<uuid::uuid> members;
            std::string username;
            if (SessionBlock::deserialize(data, sid, d_uid, d_did, members, username)) {
            std::vector<std::pair<uuid::uuid, bool>> gpo_results;
            if (SessionBlock::deserialize(data, sid, d_uid, d_did, members, username, gpo_results)) {
                uint64_t sid_gid = sidGroupId(sid);
                store_->remove_group(sid_gid);
                if (pclient_) {
@@ -426,13 +470,14 @@ namespace authdb {
    bool Cluster::fetchSessionBySid(const uuid::uuid &session_id,
                                     uuid::uuid &sid, uuid::uuid &uid, uuid::uuid &did,
                                     std::vector<uuid::uuid> &members,
                                     std::string &username) {
                                     std::string &username,
                                     std::vector<std::pair<uuid::uuid, bool>> &gpo_results) {
        uint64_t sid_gid = sidGroupId(session_id);

        // Check local store first
        std::vector<uint8_t> data;
        if (store_->fetch(sid_gid, 0, data)) {
            if (SessionBlock::deserialize(data, sid, uid, did, members, username)) {
            if (SessionBlock::deserialize(data, sid, uid, did, members, username, gpo_results)) {
                return true;
            }
        }
@@ -442,7 +487,7 @@ namespace authdb {
            try {
                std::lock_guard<std::mutex> lock(client_mutex_);
                if (pclient_->fetch_from_peers(sid_gid, 0, data) && !data.empty()) {
                    if (SessionBlock::deserialize(data, sid, uid, did, members, username)) {
                    if (SessionBlock::deserialize(data, sid, uid, did, members, username, gpo_results)) {
                        // Cache locally
                        store_->store(sid_gid, 0, data.data(), data.size());
                        return true;
+7 −3
Changes for src/cluster.h: 7 added lines, 3 removed lines.
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@
#include <mutex>
#include <thread>
#include <atomic>
#include <utility>
#include <uuidp.h>

#include <paritypp/server.h>
@@ -70,7 +71,8 @@ namespace authdb {
        static bool deserialize(const std::vector<uint8_t> &data,
                                uuid::uuid &sid, uuid::uuid &uid, uuid::uuid &did,
                                std::vector<uuid::uuid> &members,
                                std::string &username);
                                std::string &username,
                                std::vector<std::pair<uuid::uuid, bool>> &gpo_results);
    };

    uint64_t sessionGroupId(const uuid::uuid &uid, const uuid::uuid &did);
@@ -130,7 +132,8 @@ namespace authdb {
        // Returns true if found, fills out parameters
        bool fetchSession(const uuid::uuid &uid, const uuid::uuid &did,
                          uuid::uuid &sid, std::vector<uuid::uuid> &members,
                          std::string &username);
                          std::string &username,
                          std::vector<std::pair<uuid::uuid, bool>> &gpo_results);

        // Remove a session from the cluster
        void removeSession(const uuid::uuid &uid, const uuid::uuid &did);
@@ -145,7 +148,8 @@ namespace authdb {
        bool fetchSessionBySid(const uuid::uuid &session_id,
                               uuid::uuid &sid, uuid::uuid &uid, uuid::uuid &did,
                               std::vector<uuid::uuid> &members,
                               std::string &username);
                               std::string &username,
                               std::vector<std::pair<uuid::uuid, bool>> &gpo_results);

        // Replicate a data operation (create/edit/delete) to peers
        void replicateOp(OpType op, const std::string &domain,
+44 −2
Changes for src/session.cpp: 44 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -143,6 +143,44 @@ bool authdb::SessionData::checkGPO(uuid::uuid gpoid) const{
    return false;
}

void authdb::SessionData::getMembers(std::vector<uuid::uuid> &out) const{
    out = _members;
}

void authdb::SessionData::getGPOResults(std::vector<std::pair<uuid::uuid, bool>> &out) const{
    out.clear();
    for(const GPOResult *cures=&_GPOResult; cures; cures=cures->next){
        if(!cures->GPOId.empty()){
            out.emplace_back(cures->GPOId, cures->GPORes);
        }
    }
}

void authdb::SessionData::setGPOResults(const std::vector<std::pair<uuid::uuid, bool>> &results){
    // Clear existing GPO results (except the embedded first one)
    while(_GPOResult.next){
        GPOResult *ne=_GPOResult.next->next;
        _GPOResult.next->next=nullptr;
        delete _GPOResult.next;
        _GPOResult.next=ne;
    }
    _GPOResult.GPOId.clear();
    _GPOResult.GPORes=false;

    GPOResult *cur=&_GPOResult;
    for(size_t i=0; i<results.size(); ++i){
        if(i==0){
            cur->GPOId=results[i].first;
            cur->GPORes=results[i].second;
        }else{
            cur->next=new GPOResult();
            cur=cur->next;
            cur->GPOId=results[i].first;
            cur->GPORes=results[i].second;
        }
    }
}

authdb::Session::Session() {
    _firstData=nullptr;
    _lastData=nullptr;
@@ -202,11 +240,13 @@ const authdb::SessionData *authdb::Session::addSession(AuthBackend &backend,uuid
        uuid::uuid cluster_sid;
        std::vector<uuid::uuid> cluster_members;
        std::string cluster_username;
        std::vector<std::pair<uuid::uuid, bool>> cluster_gpo;
        if (g_Cluster->fetchSession(userid, domainid, cluster_sid,
                                     cluster_members, cluster_username)) {
                                     cluster_members, cluster_username, cluster_gpo)) {
            // Session exists on another node, import it locally
            SessionData *imported = new SessionData(cluster_sid, userid, domainid, cluster_members);
            imported->_username = cluster_username;
            imported->setGPOResults(cluster_gpo);

            std::lock_guard<std::mutex> guard(_SessionLock);
            if (!_firstData) {
@@ -395,9 +435,11 @@ const authdb::SessionData *authdb::Session::getSession(uuid::uuid sessionid){
        uuid::uuid sid, uid, did;
        std::vector<uuid::uuid> members;
        std::string username;
        if (g_Cluster->fetchSessionBySid(sessionid, sid, uid, did, members, username)) {
        std::vector<std::pair<uuid::uuid, bool>> gpo_results;
        if (g_Cluster->fetchSessionBySid(sessionid, sid, uid, did, members, username, gpo_results)) {
            SessionData *imported = new SessionData(sid, uid, did, members);
            imported->_username = username;
            imported->setGPOResults(gpo_results);

            std::lock_guard<std::mutex> guard(_SessionLock);
            if (!_firstData) {
+5 −0
Changes for src/session.h: 5 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@
#include <memory>
#include <mutex>
#include <chrono>
#include <utility>
#include <uuidp.h>

#include "authdb.h"
@@ -70,6 +71,10 @@ namespace authdb {

        bool checkGPO(uuid::uuid gpoid) const;

        void getMembers(std::vector<uuid::uuid> &out) const;
        void getGPOResults(std::vector<std::pair<uuid::uuid, bool>> &out) const;
        void setGPOResults(const std::vector<std::pair<uuid::uuid, bool>> &results);

    private:

        class GPOResult{