Commit 3bd4ce82 authored by jan.koester's avatar jan.koester
Browse files

bugfix

parent d8389d91
Loading
Loading
Loading
Loading
Loading
+3 −27
Changes for src/api.cpp: 3 added lines, 27 removed lines.
Original line number Diff line number Diff line
@@ -802,35 +802,11 @@ public:
                    json_object* out = json_object_new_object();
                    json_object* jarr = json_object_new_array();

                    Group group;
                    std::vector<uuid::uuid> gids;
                    group.list(_Backend, gids);
                    for (auto &gid : gids) {
                        class GroupData gdat(gid);
                        try {
                            size_t upos = sizeof(fenrirds::AuthHeader);
                            group.info(_Backend, gdat, upos);

                    for (const GroupRef &g : allGroups(_Backend)) {
                        json_object *jgrp = json_object_new_object();
                            json_object_object_add(jgrp, "gid", json_object_new_string(gid.c_str()));
                            json_object_object_add(jgrp, "name", json_object_new_string(gdat.getName().c_str()));
                        json_object_object_add(jgrp, "gid", json_object_new_string(g.gid.c_str()));
                        json_object_object_add(jgrp, "name", json_object_new_string(g.name.c_str()));
                        json_object_array_add(jarr, jgrp);
                        } catch (AuthBackendError &e) {
                            std::cerr << e.what() << std::endl;
                        }
                    }

                    /* a domain's admins are a directory group, not a native
                     * one; clients need its id to grant their GPOs to it */
                    if (g_AdPlugin) {
                        dsdb::Entry admins;
                        std::string err;
                        if (g_AdPlugin->dirGetBySam(_Backend.getDomain(), "Domain Admins", admins, err)) {
                            json_object *jgrp = json_object_new_object();
                            json_object_object_add(jgrp, "gid", json_object_new_string(admins.objectGuid.c_str()));
                            json_object_object_add(jgrp, "name", json_object_new_string("Domain Admins"));
                            json_object_array_add(jarr, jgrp);
                        }
                    }

                    json_object_object_add(out, "groups", jarr);
+57 −0
Changes for src/group.cpp: 57 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@
#include "group.h"
#include "index.h"
#include "exception.h"
#include "plugin.h"

fenrirds::GroupData::GroupData(uuid::uuid gid) : AuthData(gid){
    _Name=nullptr;
@@ -211,6 +212,62 @@ bool fenrirds::Group::exits(AuthBackend& backend,const uuid::uuid &gid, const st
    return false;
}

std::vector<fenrirds::GroupRef> fenrirds::allGroups(AuthBackend &backend){
    std::vector<GroupRef> out;
    if (g_AdPlugin) {
        std::vector<dsdb::Entry> ents;
        std::string err;
        if (g_AdPlugin->dirList(backend.getDomain(), AdPlugin::DirGroup, ents, err))
            for (const auto &e : ents)
                out.push_back({e.objectGuid, e.str("sAMAccountName")});
    }
    Group group;
    std::vector<uuid::uuid> gids;
    group.list(backend, gids);
    for (const auto &gid : gids) {
        bool known = false;
        for (const auto &g : out)
            if (g.gid == gid) known = true;
        if (known) continue;
        class GroupData gdat(gid);
        try {
            size_t pos = sizeof(AuthHeader);
            group.info(backend, gdat, pos);
            out.push_back({gid, gdat.getName()});
        } catch (const AuthBackendError &e) {
            std::cerr << e.what() << std::endl;
        }
    }
    return out;
}

std::vector<uuid::uuid> fenrirds::groupsOfUser(AuthBackend &backend, const uuid::uuid &uid){
    std::vector<uuid::uuid> out;
    if (g_AdPlugin) {
        std::string err;
        g_AdPlugin->dirMemberships(backend.getDomain(), uid, out, err);
    }
    Group group;
    std::vector<uuid::uuid> gids;
    group.list(backend, gids);
    for (const auto &gid : gids) {
        class GroupData gdat(gid);
        try {
            size_t pos = sizeof(AuthHeader);
            group.info(backend, gdat, pos);
            if (gdat.isMember(uid)) {
                bool known = false;
                for (const auto &g : out)
                    if (g == gid) known = true;
                if (!known) out.push_back(gid);
            }
        } catch (const AuthBackendError &e) {
            std::cerr << e.what() << std::endl;
        }
    }
    return out;
}

void fenrirds::Group::create(AuthBackend& backend, class GroupData* dat){
    AuthBackend::Guard guard(backend);
    int exi=0;
+10 −0
Changes for src/group.h: 10 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -34,6 +34,16 @@
#pragma once

namespace fenrirds {
    /* The groups as everything except their CRUD should see them: the
     * directory's, plus native ones where one still exists (the bootstrap
     * SuperAdmin group of admin.local, which predates any directory). */
    struct GroupRef {
        uuid::uuid  gid;
        std::string name;
    };
    std::vector<GroupRef> allGroups(AuthBackend &backend);
    std::vector<uuid::uuid> groupsOfUser(AuthBackend &backend, const uuid::uuid &uid);

    class GroupData : public AuthData{
    public:

+12 −28
Changes for src/session.cpp: 12 added lines, 28 removed lines.
Original line number Diff line number Diff line
@@ -288,13 +288,11 @@ SessionData *createSessionData(AuthBackend &backend, uuid::uuid domainid, uuid::
        dsdb::Entry e;
        if (g_AdPlugin->dirGet(domain, userid, e, err))
            username = e.str("sAMAccountName");
        std::vector<uuid::uuid> groups;
        if (g_AdPlugin->dirMemberships(domain, userid, groups, err))
            *mbs = groups;
    }
    *mbs = groupsOfUser(backend, userid);

    /* Fallback for the bootstrap SuperAdmin / legacy native accounts that are
     * not directory objects: read username + group membership natively. */
     * not directory objects: read the username natively. */
    if (username.empty()) {
        try {
            User user;
@@ -302,16 +300,6 @@ SessionData *createSessionData(AuthBackend &backend, uuid::uuid domainid, uuid::
            size_t upos = sizeof(AuthHeader);
            user.info(backend, udat, upos);
            username = udat.getUsername();
            Group group;
            std::vector<uuid::uuid> gids;
            group.list(backend, gids);
            for (auto &gid : gids) {
                std::shared_ptr<class GroupData> grpi = std::make_shared<class GroupData>(gid);
                size_t gpos = sizeof(AuthHeader);
                group.info(backend, *grpi, gpos);
                if (grpi->isMember(userid))
                    mbs->emplace_back(gid);
            }
        } catch (...) {
            /* leave username empty */
        }
@@ -383,28 +371,24 @@ SessionData *createSessionData(AuthBackend &backend, uuid::uuid domainid, uuid::
}

void reloadSessionData(AuthBackend &backend, SessionData *cursess){
    Group group;
    std::string username;

    cursess->_members.clear();

    // Get username via User::info
    uuid::uuid uid(cursess->_uid);
    if (g_AdPlugin) {
        std::string err;
        dsdb::Entry e;
        if (g_AdPlugin->dirGet(backend.getDomain(), uid, e, err))
            username = e.str("sAMAccountName");
    }
    if (username.empty()) {
        User user;
        class UserData udat(cursess->_uid.value);
        size_t upos=sizeof(AuthHeader);
        user.info(backend, udat, upos);
        username=udat.getUsername();

    // Collect group memberships
    std::vector<uuid::uuid> gids;
    group.list(backend, gids);
    for(auto &gid : gids){
        std::shared_ptr<class GroupData> grpi=std::make_shared<class GroupData>(gid);
        size_t gpos=sizeof(AuthHeader);
        group.info(backend,*grpi,gpos);
        if(grpi->isMember(cursess->_uid.value))
            cursess->_members.emplace_back(gid);
    }

    cursess->_members = groupsOfUser(backend, uid);
    cursess->_username=username;

    // Re-evaluate GPOs as well (same rules as createSessionData); otherwise new or