Loading src/admin.cpp +29 −38 Original line number Diff line number Diff line Loading @@ -509,43 +509,25 @@ namespace authdb { json_object_put(jobj); } /* ---- Helper: Check if session user is SuperAdmin from admin.local ---- */ /* ---- Helper: Check if session user has full admin rights (all authdb GPOs granted) ---- */ bool isSuperAdmin(const SessionData *sdat) { if (!sdat) return false; // Get the user ID from the session uuid::uuid uid; sdat->getUid(uid); // Find "SuperAdmin" group in admin backend and check membership Group group; std::vector<uuid::uuid> gids; group.list(_AdminBackend, gids); for (const auto &gid : gids) { class GroupData gdat(gid); try { size_t gpos = sizeof(authdb::AuthHeader); group.info(_AdminBackend, gdat, gpos); if (gdat.getName() == "SuperAdmin") { return gdat.isMember(uid); } } catch (AuthBackendError &e) { std::cerr << e.what() << std::endl; } } // SuperAdmin = user has all default GPOs granted for (size_t i = 0; gpo_default[i][0] != nullptr; ++i) { if (!sdat->checkGPO(uuid::uuid(gpo_default[i][0]))) return false; } return true; } /* ---- Helper: Check GPO permission ---- */ void checkGPO(const SessionData *sdat, const char *gpoid) { if (!sdat) throw AuthBackendError("No session!"); if (isSuperAdmin(sdat)) return; if (!sdat->checkGPO(uuid::uuid(gpoid))) throw AuthBackendError("Insufficient permissions!"); } /* ---- Helper: Check domain access (non-SuperAdmins can only access their own domain) ---- */ /* ---- Helper: Check domain access (users without full admin can only access their own domain) ---- */ void checkDomainAccess(const SessionData *sdat, const char *cdid) { if (!sdat) throw AuthBackendError("No session!"); Loading @@ -562,9 +544,9 @@ namespace authdb { // If requested domain matches session domain, allow if (sessionDomain == cdid) return; // Otherwise, must be SuperAdmin from admin.local // Otherwise, must have all GPOs (full admin) if (!isSuperAdmin(sdat)) throw AuthBackendError("Zugriff verweigert: nur SuperAdmins von admin.local duerfen andere Domains einsehen!"); throw AuthBackendError("Zugriff verweigert: keine Berechtigung fuer diese Domain!"); } /* ---- JSON API: Check Permissions ---- */ Loading Loading @@ -1904,6 +1886,9 @@ namespace authdb { char domBuf[255] = {}; if (sscanf(reqUrl.c_str(), "/settings/%[^/]/api", domBuf) == 1 && strcmp(domBuf, "admin") != 0) { // Verify exact match (no trailing path beyond /api or /api/) std::string expected = std::string("/settings/") + domBuf + "/api"; if (reqUrl == expected || reqUrl == expected + "/") { // Try parsing as UUID first, fall back to name lookup domainDid = ::uuid::uuid(domBuf); if (domainDid.empty()) { Loading @@ -1915,6 +1900,7 @@ namespace authdb { std::string(domBuf), domainDid); } } } AuthBackend::Guard guard(_AdminBackend, AuthBackend::Shared); ApiController(_AdminBackend, domainDid, curreq, tid, args); return; Loading Loading @@ -2061,8 +2047,13 @@ namespace authdb { char domBuf[255] = {}; bool isApiPath = (reqUrl == "/settings/admin/api" || reqUrl == "/settings/admin/api/"); if (!isApiPath) { // Match /settings/{domain}/api or /settings/{domain}/api/ isApiPath = (sscanf(reqUrl.c_str(), "/settings/%[^/]/api", domBuf) == 1); // Match exactly /settings/{domain}/api or /settings/{domain}/api/ char trail[2] = {}; if (sscanf(reqUrl.c_str(), "/settings/%[^/]/api%1[/]", domBuf, trail) >= 1) { // Verify nothing else follows after /api or /api/ std::string expected = std::string("/settings/") + domBuf + "/api"; isApiPath = (reqUrl == expected || reqUrl == expected + "/"); } } if (isApiPath) { libhttppp::HttpHeader::HeaderData *ct = nullptr; Loading Loading
src/admin.cpp +29 −38 Original line number Diff line number Diff line Loading @@ -509,43 +509,25 @@ namespace authdb { json_object_put(jobj); } /* ---- Helper: Check if session user is SuperAdmin from admin.local ---- */ /* ---- Helper: Check if session user has full admin rights (all authdb GPOs granted) ---- */ bool isSuperAdmin(const SessionData *sdat) { if (!sdat) return false; // Get the user ID from the session uuid::uuid uid; sdat->getUid(uid); // Find "SuperAdmin" group in admin backend and check membership Group group; std::vector<uuid::uuid> gids; group.list(_AdminBackend, gids); for (const auto &gid : gids) { class GroupData gdat(gid); try { size_t gpos = sizeof(authdb::AuthHeader); group.info(_AdminBackend, gdat, gpos); if (gdat.getName() == "SuperAdmin") { return gdat.isMember(uid); } } catch (AuthBackendError &e) { std::cerr << e.what() << std::endl; } } // SuperAdmin = user has all default GPOs granted for (size_t i = 0; gpo_default[i][0] != nullptr; ++i) { if (!sdat->checkGPO(uuid::uuid(gpo_default[i][0]))) return false; } return true; } /* ---- Helper: Check GPO permission ---- */ void checkGPO(const SessionData *sdat, const char *gpoid) { if (!sdat) throw AuthBackendError("No session!"); if (isSuperAdmin(sdat)) return; if (!sdat->checkGPO(uuid::uuid(gpoid))) throw AuthBackendError("Insufficient permissions!"); } /* ---- Helper: Check domain access (non-SuperAdmins can only access their own domain) ---- */ /* ---- Helper: Check domain access (users without full admin can only access their own domain) ---- */ void checkDomainAccess(const SessionData *sdat, const char *cdid) { if (!sdat) throw AuthBackendError("No session!"); Loading @@ -562,9 +544,9 @@ namespace authdb { // If requested domain matches session domain, allow if (sessionDomain == cdid) return; // Otherwise, must be SuperAdmin from admin.local // Otherwise, must have all GPOs (full admin) if (!isSuperAdmin(sdat)) throw AuthBackendError("Zugriff verweigert: nur SuperAdmins von admin.local duerfen andere Domains einsehen!"); throw AuthBackendError("Zugriff verweigert: keine Berechtigung fuer diese Domain!"); } /* ---- JSON API: Check Permissions ---- */ Loading Loading @@ -1904,6 +1886,9 @@ namespace authdb { char domBuf[255] = {}; if (sscanf(reqUrl.c_str(), "/settings/%[^/]/api", domBuf) == 1 && strcmp(domBuf, "admin") != 0) { // Verify exact match (no trailing path beyond /api or /api/) std::string expected = std::string("/settings/") + domBuf + "/api"; if (reqUrl == expected || reqUrl == expected + "/") { // Try parsing as UUID first, fall back to name lookup domainDid = ::uuid::uuid(domBuf); if (domainDid.empty()) { Loading @@ -1915,6 +1900,7 @@ namespace authdb { std::string(domBuf), domainDid); } } } AuthBackend::Guard guard(_AdminBackend, AuthBackend::Shared); ApiController(_AdminBackend, domainDid, curreq, tid, args); return; Loading Loading @@ -2061,8 +2047,13 @@ namespace authdb { char domBuf[255] = {}; bool isApiPath = (reqUrl == "/settings/admin/api" || reqUrl == "/settings/admin/api/"); if (!isApiPath) { // Match /settings/{domain}/api or /settings/{domain}/api/ isApiPath = (sscanf(reqUrl.c_str(), "/settings/%[^/]/api", domBuf) == 1); // Match exactly /settings/{domain}/api or /settings/{domain}/api/ char trail[2] = {}; if (sscanf(reqUrl.c_str(), "/settings/%[^/]/api%1[/]", domBuf, trail) >= 1) { // Verify nothing else follows after /api or /api/ std::string expected = std::string("/settings/") + domBuf + "/api"; isApiPath = (reqUrl == expected || reqUrl == expected + "/"); } } if (isApiPath) { libhttppp::HttpHeader::HeaderData *ct = nullptr; Loading