@@ -777,12 +777,21 @@ namespace {
777777 }
778778 }
779779
780- Status _initializeUserRolesFromV1PrivilegeDocument (
781- User* user, const BSONObj& privDoc, const StringData& dbname) {
780+ Status _initializeUserRolesFromV1RolesArray (User* user,
781+ const BSONElement& rolesElement,
782+ const StringData& dbname) {
782783 static const char privilegesTypeMismatchMessage[] =
783- " Roles in V1 user documents must be enumerated in an array of strings." ;
784+ " Roles in V1 user documents must be enumerated in an array of strings." ;
785+
786+ if (dbname == PrivilegeSet::WILDCARD_RESOURCE) {
787+ return Status (ErrorCodes::BadValue,
788+ PrivilegeSet::WILDCARD_RESOURCE + " is an invalid database name." );
789+ }
790+
791+ if (rolesElement.type () != Array)
792+ return Status (ErrorCodes::TypeMismatch, privilegesTypeMismatchMessage);
784793
785- for (BSONObjIterator iter (privDoc[ " roles " ] .embeddedObject ()); iter.more (); iter.next ()) {
794+ for (BSONObjIterator iter (rolesElement .embeddedObject ()); iter.more (); iter.next ()) {
786795 BSONElement roleElement = *iter;
787796 if (roleElement.type () != String)
788797 return Status (ErrorCodes::TypeMismatch, privilegesTypeMismatchMessage);
@@ -792,6 +801,48 @@ namespace {
792801 return Status::OK ();
793802 }
794803
804+ Status _initializeUserRolesFromV1PrivilegeDocument (
805+ User* user, const BSONObj& privDoc, const StringData& dbname) {
806+ Status status = _initializeUserRolesFromV1RolesArray (user,
807+ privDoc[ROLES_FIELD_NAME],
808+ dbname);
809+ if (!status.isOK ()) {
810+ return status;
811+ }
812+
813+ // If "dbname" is the admin database, handle the otherDBPrivileges field, which
814+ // grants privileges on databases other than "dbname".
815+ BSONElement otherDbPrivileges = privDoc[OTHER_DB_ROLES_FIELD_NAME];
816+ if (dbname == ADMIN_DBNAME) {
817+ switch (otherDbPrivileges.type ()) {
818+ case EOO:
819+ break ;
820+ case Object: {
821+ for (BSONObjIterator iter (otherDbPrivileges.embeddedObject ());
822+ iter.more (); iter.next ()) {
823+
824+ BSONElement rolesElement = *iter;
825+ status = _initializeUserRolesFromV1RolesArray (user,
826+ rolesElement,
827+ rolesElement.fieldName ());
828+ if (!status.isOK ())
829+ return status;
830+ }
831+ break ;
832+ }
833+ default :
834+ return Status (ErrorCodes::TypeMismatch,
835+ " Field \" otherDBRoles\" must be an object, if present." );
836+ }
837+ }
838+ else if (!otherDbPrivileges.eoo ()) {
839+ return Status (ErrorCodes::BadValue, " Only the admin database may contain a field "
840+ " called \" otherDBRoles\" " );
841+ }
842+
843+ return Status::OK ();
844+ }
845+
795846 /* *
796847 * Parses privDoc and initializes the user's "roles" field with the role list extracted
797848 * from the privilege document.
0 commit comments