diff options
author | Sara Golemon <sara.golemon@mongodb.com> | 2022-02-24 16:24:43 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-02-28 23:25:56 +0000 |
commit | 7584bddbd31e6d803ffd950e134390e97ba25f84 (patch) | |
tree | ad0fe35171ff78b1776475826f70a60c363555e6 | |
parent | 71d70bf5ebba88a8f51a20d660cb4d9c6532f35c (diff) | |
download | mongo-7584bddbd31e6d803ffd950e134390e97ba25f84.tar.gz |
SERVER-63968 Prohibit ennumeration of builtin roles on $external database
(cherry picked from commit 59df956365a44cc63e2d3c55d1734ee960891a8b)
-rw-r--r-- | jstests/core/builtin_roles_external.js | 47 | ||||
-rw-r--r-- | src/mongo/db/auth/builtin_roles.cpp | 18 | ||||
-rw-r--r-- | src/mongo/db/namespace_string.h | 3 |
3 files changed, 64 insertions, 4 deletions
diff --git a/jstests/core/builtin_roles_external.js b/jstests/core/builtin_roles_external.js new file mode 100644 index 00000000000..f2b9263cd5d --- /dev/null +++ b/jstests/core/builtin_roles_external.js @@ -0,0 +1,47 @@ +/** + * Attempting to enumerate roles on the $external database should return an empty set. + * @tags: [requires_fcv_60,tenant_migration_incompatible] + */ +(function() { +"use strict"; + +function assertBuiltinRoles(dbname, shouldHaveRoles) { + const allRoles = assert + .commandWorked(db.getSiblingDB(dbname).runCommand( + {rolesInfo: 1, showBuiltinRoles: 1, showPrivileges: 1})) + .roles; + jsTest.log(dbname + ' roles: ' + tojson(allRoles)); + + const builtinRoles = allRoles.filter((r) => r.isBuiltin); + if (shouldHaveRoles) { + assert.gt(builtinRoles.length, 0, dbname + ' should have builtin roles, but none returned'); + + function assertRole(role, expect = true) { + const filtered = builtinRoles.filter((r) => r.role === role); + if (expect) { + assert.gt( + filtered.length, 0, dbname + ' should have role ' + role + ' but does not'); + } else { + assert.eq( + filtered.length, + 0, + dbname + ' should have not role ' + role + ' but does: ' + tojson(filtered)); + } + } + + assertRole('read'); + assertRole('readWrite'); + assertRole('readWriteAnyDatabase', dbname === 'admin'); + assertRole('hostManager', dbname === 'admin'); + } else { + assert.eq(builtinRoles.length, + 0, + dbname + ' should not have builtin roles, found: ' + tojson(builtinRoles)); + } +} + +assertBuiltinRoles('admin', true); +assertBuiltinRoles('test', true); +assertBuiltinRoles('$external', false); +assertBuiltinRoles('$test', true); +}()); diff --git a/src/mongo/db/auth/builtin_roles.cpp b/src/mongo/db/auth/builtin_roles.cpp index 7faee09e529..cf56506ca60 100644 --- a/src/mongo/db/auth/builtin_roles.cpp +++ b/src/mongo/db/auth/builtin_roles.cpp @@ -768,9 +768,21 @@ const std::map<StringData, BuiltinRoleDefinition> kBuiltinRoles({ {BUILTIN_ROLE_INTERNAL, {true, addInternalRolePrivileges}}, }); +// $external is a virtual database used for X509, LDAP, +// and other authentication mechanisms and not used for storage. +// Therefore, granting privileges on this database does not make sense. +bool isValidDB(StringData dbname) { + return NamespaceString::validDBName(dbname, NamespaceString::DollarInDbNameBehavior::Allow) && + (dbname != NamespaceString::kExternalDb); +} + } // namespace stdx::unordered_set<RoleName> auth::getBuiltinRoleNamesForDB(StringData dbname) { + if (!isValidDB(dbname)) { + return {}; + } + const bool isAdmin = dbname == ADMIN_DBNAME; stdx::unordered_set<RoleName> roleNames; @@ -786,8 +798,7 @@ bool auth::addPrivilegesForBuiltinRole(const RoleName& roleName, PrivilegeVector auto role = roleName.getRole(); auto dbname = roleName.getDB(); - if (!NamespaceString::validDBName(dbname, NamespaceString::DollarInDbNameBehavior::Allow) || - dbname == "$external") { + if (!isValidDB(dbname)) { return false; } @@ -814,8 +825,7 @@ void auth::generateUniversalPrivileges(PrivilegeVector* privileges) { bool auth::isBuiltinRole(const RoleName& role) { auto dbname = role.getDB(); - if (!NamespaceString::validDBName(dbname, NamespaceString::DollarInDbNameBehavior::Allow) || - dbname == "$external") { + if (!isValidDB(dbname)) { return false; } diff --git a/src/mongo/db/namespace_string.h b/src/mongo/db/namespace_string.h index ff7b93a983a..cb90a3dde39 100644 --- a/src/mongo/db/namespace_string.h +++ b/src/mongo/db/namespace_string.h @@ -68,6 +68,9 @@ public: // Namespace for the sharding config database static constexpr StringData kConfigDb = "config"_sd; + // The $external database used by X.509, LDAP, etc... + static constexpr StringData kExternalDb = "$external"_sd; + // Name for the system views collection static constexpr StringData kSystemDotViewsCollectionName = "system.views"_sd; |