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