Loading src/api.cpp +3 −27 Changes for src/api.cpp: 3 added lines, 27 removed lines. Original line number Diff line number Diff line Loading @@ -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); Loading src/group.cpp +57 −0 Changes for src/group.cpp: 57 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading src/group.h +10 −0 Changes for src/group.h: 10 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -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: Loading src/session.cpp +12 −28 Changes for src/session.cpp: 12 added lines, 28 removed lines. Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 */ } Loading Loading @@ -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 Loading Loading
src/api.cpp +3 −27 Changes for src/api.cpp: 3 added lines, 27 removed lines. Original line number Diff line number Diff line Loading @@ -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); Loading
src/group.cpp +57 −0 Changes for src/group.cpp: 57 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading
src/group.h +10 −0 Changes for src/group.h: 10 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -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: Loading
src/session.cpp +12 −28 Changes for src/session.cpp: 12 added lines, 28 removed lines. Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 */ } Loading Loading @@ -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 Loading