1 
2 /**
3  *    Copyright (C) 2018-present MongoDB, Inc.
4  *
5  *    This program is free software: you can redistribute it and/or modify
6  *    it under the terms of the Server Side Public License, version 1,
7  *    as published by MongoDB, Inc.
8  *
9  *    This program is distributed in the hope that it will be useful,
10  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *    Server Side Public License for more details.
13  *
14  *    You should have received a copy of the Server Side Public License
15  *    along with this program. If not, see
16  *    <http://www.mongodb.com/licensing/server-side-public-license>.
17  *
18  *    As a special exception, the copyright holders give permission to link the
19  *    code of portions of this program with the OpenSSL library under certain
20  *    conditions as described in each individual source file and distribute
21  *    linked combinations including the program with the OpenSSL library. You
22  *    must comply with the Server Side Public License in all respects for
23  *    all of the code used other than as permitted herein. If you modify file(s)
24  *    with this exception, you may extend this exception to your version of the
25  *    file(s), but you are not obligated to do so. If you do not wish to do so,
26  *    delete this exception statement from your version. If you delete this
27  *    exception statement from all source files in the program, then also delete
28  *    it in the license file.
29  */
30 
31 #define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kAccessControl
32 
33 #include "mongo/platform/basic.h"
34 
35 #include "mongo/db/commands/user_management_commands.h"
36 
37 #include <string>
38 #include <vector>
39 
40 #include "mongo/base/status.h"
41 #include "mongo/bson/mutable/algorithm.h"
42 #include "mongo/config.h"
43 #include "mongo/db/auth/action_set.h"
44 #include "mongo/db/auth/action_type.h"
45 #include "mongo/db/auth/authorization_session.h"
46 #include "mongo/db/auth/resource_pattern.h"
47 #include "mongo/db/auth/user.h"
48 #include "mongo/db/auth/user_management_commands_parser.h"
49 #include "mongo/db/jsobj.h"
50 #include "mongo/util/log.h"
51 #include "mongo/util/mongoutils/str.h"
52 #include "mongo/util/sequence_util.h"
53 
54 namespace mongo {
55 namespace auth {
56 
redactPasswordData(mutablebson::Element parent)57 void redactPasswordData(mutablebson::Element parent) {
58     namespace mmb = mutablebson;
59     const auto pwdFieldName = "pwd"_sd;
60     for (mmb::Element pwdElement = mmb::findFirstChildNamed(parent, pwdFieldName); pwdElement.ok();
61          pwdElement = mmb::findElementNamed(pwdElement.rightSibling(), pwdFieldName)) {
62         pwdElement.setValueString("xxx").transitional_ignore();
63     }
64 }
65 
checkAuthorizedToGrantRoles(AuthorizationSession * authzSession,const std::vector<RoleName> & roles)66 Status checkAuthorizedToGrantRoles(AuthorizationSession* authzSession,
67                                    const std::vector<RoleName>& roles) {
68     for (size_t i = 0; i < roles.size(); ++i) {
69         if (!authzSession->isAuthorizedToGrantRole(roles[i])) {
70             return Status(ErrorCodes::Unauthorized,
71                           str::stream() << "Not authorized to grant role: "
72                                         << roles[i].getFullName());
73         }
74     }
75 
76     return Status::OK();
77 }
78 
checkAuthorizedToGrantPrivileges(AuthorizationSession * authzSession,const PrivilegeVector & privileges)79 Status checkAuthorizedToGrantPrivileges(AuthorizationSession* authzSession,
80                                         const PrivilegeVector& privileges) {
81     for (PrivilegeVector::const_iterator it = privileges.begin(); it != privileges.end(); ++it) {
82         Status status = authzSession->checkAuthorizedToGrantPrivilege(*it);
83         if (!status.isOK()) {
84             return status;
85         }
86     }
87 
88     return Status::OK();
89 }
90 
checkAuthorizedToRevokeRoles(AuthorizationSession * authzSession,const std::vector<RoleName> & roles)91 Status checkAuthorizedToRevokeRoles(AuthorizationSession* authzSession,
92                                     const std::vector<RoleName>& roles) {
93     for (size_t i = 0; i < roles.size(); ++i) {
94         if (!authzSession->isAuthorizedToRevokeRole(roles[i])) {
95             return Status(ErrorCodes::Unauthorized,
96                           str::stream() << "Not authorized to revoke role: "
97                                         << roles[i].getFullName());
98         }
99     }
100     return Status::OK();
101 }
102 
checkAuthorizedToRevokePrivileges(AuthorizationSession * authzSession,const PrivilegeVector & privileges)103 Status checkAuthorizedToRevokePrivileges(AuthorizationSession* authzSession,
104                                          const PrivilegeVector& privileges) {
105     for (PrivilegeVector::const_iterator it = privileges.begin(); it != privileges.end(); ++it) {
106         Status status = authzSession->checkAuthorizedToRevokePrivilege(*it);
107         if (!status.isOK()) {
108             return status;
109         }
110     }
111 
112     return Status::OK();
113 }
114 
checkAuthorizedToSetRestrictions(AuthorizationSession * authzSession,bool hasAuthRestriction,StringData dbname)115 Status checkAuthorizedToSetRestrictions(AuthorizationSession* authzSession,
116                                         bool hasAuthRestriction,
117                                         StringData dbname) {
118     if (hasAuthRestriction) {
119         if (!authzSession->isAuthorizedForActionsOnResource(
120                 ResourcePattern::forDatabaseName(dbname),
121                 ActionType::setAuthenticationRestriction)) {
122             return Status(ErrorCodes::Unauthorized, "Unauthorized");
123         }
124     }
125 
126     return Status::OK();
127 }
128 
checkAuthForCreateUserCommand(Client * client,const std::string & dbname,const BSONObj & cmdObj)129 Status checkAuthForCreateUserCommand(Client* client,
130                                      const std::string& dbname,
131                                      const BSONObj& cmdObj) {
132     AuthorizationSession* authzSession = AuthorizationSession::get(client);
133     auth::CreateOrUpdateUserArgs args;
134     Status status = auth::parseCreateOrUpdateUserCommands(cmdObj, "createUser", dbname, &args);
135     if (!status.isOK()) {
136         return status;
137     }
138 
139     if (!authzSession->isAuthorizedForActionsOnResource(
140             ResourcePattern::forDatabaseName(args.userName.getDB()), ActionType::createUser)) {
141         return Status(ErrorCodes::Unauthorized,
142                       str::stream() << "Not authorized to create users on db: "
143                                     << args.userName.getDB());
144     }
145 
146     status = checkAuthorizedToGrantRoles(authzSession, args.roles);
147     if (!status.isOK()) {
148         return status;
149     }
150 
151     status = checkAuthorizedToSetRestrictions(
152         authzSession, static_cast<bool>(args.authenticationRestrictions), args.userName.getDB());
153     if (!status.isOK()) {
154         return status;
155     }
156 
157     return Status::OK();
158 }
159 
checkAuthForUpdateUserCommand(Client * client,const std::string & dbname,const BSONObj & cmdObj)160 Status checkAuthForUpdateUserCommand(Client* client,
161                                      const std::string& dbname,
162                                      const BSONObj& cmdObj) {
163     AuthorizationSession* authzSession = AuthorizationSession::get(client);
164     auth::CreateOrUpdateUserArgs args;
165     Status status = auth::parseCreateOrUpdateUserCommands(cmdObj, "updateUser", dbname, &args);
166     if (!status.isOK()) {
167         return status;
168     }
169 
170     if (args.hasHashedPassword) {
171         if (!authzSession->isAuthorizedToChangeOwnPasswordAsUser(args.userName) &&
172             !authzSession->isAuthorizedForActionsOnResource(
173                 ResourcePattern::forDatabaseName(args.userName.getDB()),
174                 ActionType::changePassword)) {
175             return Status(ErrorCodes::Unauthorized,
176                           str::stream() << "Not authorized to change password of user: "
177                                         << args.userName.getFullName());
178         }
179     }
180 
181     if (args.hasCustomData) {
182         if (!authzSession->isAuthorizedToChangeOwnCustomDataAsUser(args.userName) &&
183             !authzSession->isAuthorizedForActionsOnResource(
184                 ResourcePattern::forDatabaseName(args.userName.getDB()),
185                 ActionType::changeCustomData)) {
186             return Status(ErrorCodes::Unauthorized,
187                           str::stream() << "Not authorized to change customData of user: "
188                                         << args.userName.getFullName());
189         }
190     }
191 
192     if (args.hasRoles) {
193         // You don't know what roles you might be revoking, so require the ability to
194         // revoke any role in the system.
195         if (!authzSession->isAuthorizedForActionsOnResource(ResourcePattern::forAnyNormalResource(),
196                                                             ActionType::revokeRole)) {
197             return Status(ErrorCodes::Unauthorized,
198                           "In order to use updateUser to set roles array, must be "
199                           "authorized to revoke any role in the system");
200         }
201 
202         status = checkAuthorizedToGrantRoles(authzSession, args.roles);
203         if (!status.isOK()) {
204             return status;
205         }
206     }
207 
208     status = checkAuthorizedToSetRestrictions(
209         authzSession, static_cast<bool>(args.authenticationRestrictions), args.userName.getDB());
210     if (!status.isOK()) {
211         return status;
212     }
213 
214     return Status::OK();
215 }
216 
checkAuthForGrantRolesToUserCommand(Client * client,const std::string & dbname,const BSONObj & cmdObj)217 Status checkAuthForGrantRolesToUserCommand(Client* client,
218                                            const std::string& dbname,
219                                            const BSONObj& cmdObj) {
220     AuthorizationSession* authzSession = AuthorizationSession::get(client);
221     std::vector<RoleName> roles;
222     std::string unusedUserNameString;
223     Status status = auth::parseRolePossessionManipulationCommands(
224         cmdObj, "grantRolesToUser", dbname, &unusedUserNameString, &roles);
225     if (!status.isOK()) {
226         return status;
227     }
228 
229     return checkAuthorizedToGrantRoles(authzSession, roles);
230 }
231 
checkAuthForCreateRoleCommand(Client * client,const std::string & dbname,const BSONObj & cmdObj)232 Status checkAuthForCreateRoleCommand(Client* client,
233                                      const std::string& dbname,
234                                      const BSONObj& cmdObj) {
235     AuthorizationSession* authzSession = AuthorizationSession::get(client);
236     auth::CreateOrUpdateRoleArgs args;
237     Status status = auth::parseCreateOrUpdateRoleCommands(cmdObj, "createRole", dbname, &args);
238     if (!status.isOK()) {
239         return status;
240     }
241 
242     if (!authzSession->isAuthorizedToCreateRole(args)) {
243         return Status(ErrorCodes::Unauthorized,
244                       str::stream() << "Not authorized to create roles on db: "
245                                     << args.roleName.getDB());
246     }
247 
248     status = checkAuthorizedToGrantRoles(authzSession, args.roles);
249     if (!status.isOK()) {
250         return status;
251     }
252 
253     status = checkAuthorizedToGrantPrivileges(authzSession, args.privileges);
254     if (!status.isOK()) {
255         return status;
256     }
257 
258     status = checkAuthorizedToSetRestrictions(
259         authzSession, static_cast<bool>(args.authenticationRestrictions), args.roleName.getDB());
260     if (!status.isOK()) {
261         return status;
262     }
263 
264     return Status::OK();
265 }
266 
checkAuthForUpdateRoleCommand(Client * client,const std::string & dbname,const BSONObj & cmdObj)267 Status checkAuthForUpdateRoleCommand(Client* client,
268                                      const std::string& dbname,
269                                      const BSONObj& cmdObj) {
270     AuthorizationSession* authzSession = AuthorizationSession::get(client);
271     auth::CreateOrUpdateRoleArgs args;
272     Status status = auth::parseCreateOrUpdateRoleCommands(cmdObj, "updateRole", dbname, &args);
273     if (!status.isOK()) {
274         return status;
275     }
276 
277     // You don't know what roles or privileges you might be revoking, so require the ability
278     // to revoke any role (or privilege) in the system.
279     if (!authzSession->isAuthorizedForActionsOnResource(ResourcePattern::forAnyNormalResource(),
280                                                         ActionType::revokeRole)) {
281         return Status(ErrorCodes::Unauthorized,
282                       "updateRole command required the ability to revoke any role in the "
283                       "system");
284     }
285 
286     status = checkAuthorizedToGrantRoles(authzSession, args.roles);
287     if (!status.isOK()) {
288         return status;
289     }
290 
291     status = checkAuthorizedToGrantPrivileges(authzSession, args.privileges);
292     if (!status.isOK()) {
293         return status;
294     }
295 
296     status = checkAuthorizedToSetRestrictions(
297         authzSession, static_cast<bool>(args.authenticationRestrictions), args.roleName.getDB());
298     if (!status.isOK()) {
299         return status;
300     }
301 
302     return Status::OK();
303 }
304 
checkAuthForGrantRolesToRoleCommand(Client * client,const std::string & dbname,const BSONObj & cmdObj)305 Status checkAuthForGrantRolesToRoleCommand(Client* client,
306                                            const std::string& dbname,
307                                            const BSONObj& cmdObj) {
308     AuthorizationSession* authzSession = AuthorizationSession::get(client);
309     std::vector<RoleName> roles;
310     std::string unusedUserNameString;
311     Status status = auth::parseRolePossessionManipulationCommands(
312         cmdObj, "grantRolesToRole", dbname, &unusedUserNameString, &roles);
313     if (!status.isOK()) {
314         return status;
315     }
316 
317     return checkAuthorizedToGrantRoles(authzSession, roles);
318 }
319 
checkAuthForGrantPrivilegesToRoleCommand(Client * client,const std::string & dbname,const BSONObj & cmdObj)320 Status checkAuthForGrantPrivilegesToRoleCommand(Client* client,
321                                                 const std::string& dbname,
322                                                 const BSONObj& cmdObj) {
323     AuthorizationSession* authzSession = AuthorizationSession::get(client);
324     PrivilegeVector privileges;
325     RoleName unusedRoleName;
326     Status status = auth::parseAndValidateRolePrivilegeManipulationCommands(
327         cmdObj, "grantPrivilegesToRole", dbname, &unusedRoleName, &privileges);
328     if (!status.isOK()) {
329         return status;
330     }
331 
332     return checkAuthorizedToGrantPrivileges(authzSession, privileges);
333 }
334 
checkAuthForDropUserCommand(Client * client,const std::string & dbname,const BSONObj & cmdObj)335 Status checkAuthForDropUserCommand(Client* client,
336                                    const std::string& dbname,
337                                    const BSONObj& cmdObj) {
338     AuthorizationSession* authzSession = AuthorizationSession::get(client);
339     UserName userName;
340     Status status = auth::parseAndValidateDropUserCommand(cmdObj, dbname, &userName);
341     if (!status.isOK()) {
342         return status;
343     }
344 
345     if (!authzSession->isAuthorizedForActionsOnResource(
346             ResourcePattern::forDatabaseName(userName.getDB()), ActionType::dropUser)) {
347         return Status(ErrorCodes::Unauthorized,
348                       str::stream() << "Not authorized to drop users from the " << userName.getDB()
349                                     << " database");
350     }
351     return Status::OK();
352 }
353 
checkAuthForDropRoleCommand(Client * client,const std::string & dbname,const BSONObj & cmdObj)354 Status checkAuthForDropRoleCommand(Client* client,
355                                    const std::string& dbname,
356                                    const BSONObj& cmdObj) {
357     AuthorizationSession* authzSession = AuthorizationSession::get(client);
358     RoleName roleName;
359     Status status = auth::parseDropRoleCommand(cmdObj, dbname, &roleName);
360     if (!status.isOK()) {
361         return status;
362     }
363 
364     if (!authzSession->isAuthorizedForActionsOnResource(
365             ResourcePattern::forDatabaseName(roleName.getDB()), ActionType::dropRole)) {
366         return Status(ErrorCodes::Unauthorized,
367                       str::stream() << "Not authorized to drop roles from the " << roleName.getDB()
368                                     << " database");
369     }
370     return Status::OK();
371 }
372 
checkAuthForDropAllUsersFromDatabaseCommand(Client * client,const std::string & dbname)373 Status checkAuthForDropAllUsersFromDatabaseCommand(Client* client, const std::string& dbname) {
374     AuthorizationSession* authzSession = AuthorizationSession::get(client);
375     if (!authzSession->isAuthorizedForActionsOnResource(ResourcePattern::forDatabaseName(dbname),
376                                                         ActionType::dropUser)) {
377         return Status(ErrorCodes::Unauthorized,
378                       str::stream() << "Not authorized to drop users from the " << dbname
379                                     << " database");
380     }
381     return Status::OK();
382 }
383 
checkAuthForRevokeRolesFromUserCommand(Client * client,const std::string & dbname,const BSONObj & cmdObj)384 Status checkAuthForRevokeRolesFromUserCommand(Client* client,
385                                               const std::string& dbname,
386                                               const BSONObj& cmdObj) {
387     AuthorizationSession* authzSession = AuthorizationSession::get(client);
388     std::vector<RoleName> roles;
389     std::string unusedUserNameString;
390     Status status = auth::parseRolePossessionManipulationCommands(
391         cmdObj, "revokeRolesFromUser", dbname, &unusedUserNameString, &roles);
392     if (!status.isOK()) {
393         return status;
394     }
395 
396     return checkAuthorizedToRevokeRoles(authzSession, roles);
397 }
398 
checkAuthForRevokeRolesFromRoleCommand(Client * client,const std::string & dbname,const BSONObj & cmdObj)399 Status checkAuthForRevokeRolesFromRoleCommand(Client* client,
400                                               const std::string& dbname,
401                                               const BSONObj& cmdObj) {
402     AuthorizationSession* authzSession = AuthorizationSession::get(client);
403     std::vector<RoleName> roles;
404     std::string unusedUserNameString;
405     Status status = auth::parseRolePossessionManipulationCommands(
406         cmdObj, "revokeRolesFromRole", dbname, &unusedUserNameString, &roles);
407     if (!status.isOK()) {
408         return status;
409     }
410 
411     return checkAuthorizedToRevokeRoles(authzSession, roles);
412 }
413 
checkAuthForUsersInfoCommand(Client * client,const std::string & dbname,const BSONObj & cmdObj)414 Status checkAuthForUsersInfoCommand(Client* client,
415                                     const std::string& dbname,
416                                     const BSONObj& cmdObj) {
417     AuthorizationSession* authzSession = AuthorizationSession::get(client);
418     auth::UsersInfoArgs args;
419     Status status = auth::parseUsersInfoCommand(cmdObj, dbname, &args);
420     if (!status.isOK()) {
421         return status;
422     }
423 
424     if (args.allForDB) {
425         if (!authzSession->isAuthorizedForActionsOnResource(
426                 ResourcePattern::forDatabaseName(dbname), ActionType::viewUser)) {
427             return Status(ErrorCodes::Unauthorized,
428                           str::stream() << "Not authorized to view users from the " << dbname
429                                         << " database");
430         }
431     } else {
432         for (size_t i = 0; i < args.userNames.size(); ++i) {
433             if (authzSession->lookupUser(args.userNames[i])) {
434                 continue;  // Can always view users you are logged in as
435             }
436             if (!authzSession->isAuthorizedForActionsOnResource(
437                     ResourcePattern::forDatabaseName(args.userNames[i].getDB()),
438                     ActionType::viewUser)) {
439                 return Status(ErrorCodes::Unauthorized,
440                               str::stream() << "Not authorized to view users from the " << dbname
441                                             << " database");
442             }
443         }
444     }
445     return Status::OK();
446 }
447 
checkAuthForRevokePrivilegesFromRoleCommand(Client * client,const std::string & dbname,const BSONObj & cmdObj)448 Status checkAuthForRevokePrivilegesFromRoleCommand(Client* client,
449                                                    const std::string& dbname,
450                                                    const BSONObj& cmdObj) {
451     AuthorizationSession* authzSession = AuthorizationSession::get(client);
452     PrivilegeVector privileges;
453     RoleName unusedRoleName;
454     Status status = auth::parseAndValidateRolePrivilegeManipulationCommands(
455         cmdObj, "revokePrivilegesFromRole", dbname, &unusedRoleName, &privileges);
456     if (!status.isOK()) {
457         return status;
458     }
459 
460     return checkAuthorizedToRevokePrivileges(authzSession, privileges);
461 }
462 
checkAuthForDropAllRolesFromDatabaseCommand(Client * client,const std::string & dbname)463 Status checkAuthForDropAllRolesFromDatabaseCommand(Client* client, const std::string& dbname) {
464     AuthorizationSession* authzSession = AuthorizationSession::get(client);
465     if (!authzSession->isAuthorizedForActionsOnResource(ResourcePattern::forDatabaseName(dbname),
466                                                         ActionType::dropRole)) {
467         return Status(ErrorCodes::Unauthorized,
468                       str::stream() << "Not authorized to drop roles from the " << dbname
469                                     << " database");
470     }
471     return Status::OK();
472 }
473 
checkAuthForRolesInfoCommand(Client * client,const std::string & dbname,const BSONObj & cmdObj)474 Status checkAuthForRolesInfoCommand(Client* client,
475                                     const std::string& dbname,
476                                     const BSONObj& cmdObj) {
477     AuthorizationSession* authzSession = AuthorizationSession::get(client);
478     auth::RolesInfoArgs args;
479     Status status = auth::parseRolesInfoCommand(cmdObj, dbname, &args);
480     if (!status.isOK()) {
481         return status;
482     }
483 
484     if (args.allForDB) {
485         if (!authzSession->isAuthorizedForActionsOnResource(
486                 ResourcePattern::forDatabaseName(dbname), ActionType::viewRole)) {
487             return Status(ErrorCodes::Unauthorized,
488                           str::stream() << "Not authorized to view roles from the " << dbname
489                                         << " database");
490         }
491     } else {
492         for (size_t i = 0; i < args.roleNames.size(); ++i) {
493             if (authzSession->isAuthenticatedAsUserWithRole(args.roleNames[i])) {
494                 continue;  // Can always see roles that you are a member of
495             }
496 
497             if (!authzSession->isAuthorizedForActionsOnResource(
498                     ResourcePattern::forDatabaseName(args.roleNames[i].getDB()),
499                     ActionType::viewRole)) {
500                 return Status(ErrorCodes::Unauthorized,
501                               str::stream() << "Not authorized to view roles from the "
502                                             << args.roleNames[i].getDB()
503                                             << " database");
504             }
505         }
506     }
507 
508     return Status::OK();
509 }
510 
checkAuthForInvalidateUserCacheCommand(Client * client)511 Status checkAuthForInvalidateUserCacheCommand(Client* client) {
512     AuthorizationSession* authzSession = AuthorizationSession::get(client);
513     if (!authzSession->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
514                                                         ActionType::invalidateUserCache)) {
515         return Status(ErrorCodes::Unauthorized, "Not authorized to invalidate user cache");
516     }
517     return Status::OK();
518 }
519 
checkAuthForGetUserCacheGenerationCommand(Client * client)520 Status checkAuthForGetUserCacheGenerationCommand(Client* client) {
521     AuthorizationSession* authzSession = AuthorizationSession::get(client);
522     if (!authzSession->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
523                                                         ActionType::internal)) {
524         return Status(ErrorCodes::Unauthorized, "Not authorized to get cache generation");
525     }
526     return Status::OK();
527 }
528 
checkAuthForMergeAuthzCollectionsCommand(Client * client,const BSONObj & cmdObj)529 Status checkAuthForMergeAuthzCollectionsCommand(Client* client, const BSONObj& cmdObj) {
530     auth::MergeAuthzCollectionsArgs args;
531     Status status = auth::parseMergeAuthzCollectionsCommand(cmdObj, &args);
532     if (!status.isOK()) {
533         return status;
534     }
535 
536     AuthorizationSession* authzSession = AuthorizationSession::get(client);
537     ActionSet actions;
538     actions.addAction(ActionType::createUser);
539     actions.addAction(ActionType::createRole);
540     actions.addAction(ActionType::grantRole);
541     actions.addAction(ActionType::revokeRole);
542     if (args.drop) {
543         actions.addAction(ActionType::dropUser);
544         actions.addAction(ActionType::dropRole);
545     }
546     if (!authzSession->isAuthorizedForActionsOnResource(ResourcePattern::forAnyNormalResource(),
547                                                         actions)) {
548         return Status(ErrorCodes::Unauthorized,
549                       "Not authorized to update user/role data using _mergeAuthzCollections"
550                       " command");
551     }
552     if (!args.usersCollName.empty() &&
553         !authzSession->isAuthorizedForActionsOnResource(
554             ResourcePattern::forExactNamespace(NamespaceString(args.usersCollName)),
555             ActionType::find)) {
556         return Status(ErrorCodes::Unauthorized,
557                       str::stream() << "Not authorized to read " << args.usersCollName);
558     }
559     if (!args.rolesCollName.empty() &&
560         !authzSession->isAuthorizedForActionsOnResource(
561             ResourcePattern::forExactNamespace(NamespaceString(args.rolesCollName)),
562             ActionType::find)) {
563         return Status(ErrorCodes::Unauthorized,
564                       str::stream() << "Not authorized to read " << args.rolesCollName);
565     }
566     return Status::OK();
567 }
568 
checkAuthForAuthSchemaUpgradeCommand(Client * client)569 Status checkAuthForAuthSchemaUpgradeCommand(Client* client) {
570     AuthorizationSession* authzSession = AuthorizationSession::get(client);
571     if (!authzSession->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
572                                                         ActionType::authSchemaUpgrade)) {
573         return Status(ErrorCodes::Unauthorized, "Not authorized to run authSchemaUpgrade command.");
574     }
575     return Status::OK();
576 }
577 
578 }  // namespace auth
579 }  // namespace mongo
580