    bool run(OperationContext* opCtx,
             const string& dbname,
             const BSONObj& cmdObj,
             BSONObjBuilder& result) {
        auth::CreateOrUpdateUserArgs args;
        Status status = auth::parseCreateOrUpdateUserCommands(cmdObj, "createUser", dbname, &args);
        uassertStatusOK(status);

        if (args.userName.getDB() == "local") {
            uasserted(ErrorCodes::BadValue, "Cannot create users in the local database");
        }

        if (!args.hasPassword && args.userName.getDB() != "$external") {
            uasserted(ErrorCodes::BadValue,
                      "Must provide a 'pwd' field for all user documents, except those"
                      " with '$external' as the user's source db");
        }

        if ((args.hasPassword) && args.userName.getDB() == "$external") {
            uasserted(ErrorCodes::BadValue,
                      "Cannot set the password for users defined on the '$external' "
                      "database");
        }

        if (!args.hasRoles) {
            uasserted(ErrorCodes::BadValue, "\"createUser\" command requires a \"roles\" array");
        }

#ifdef MONGO_CONFIG_SSL
        if (args.userName.getDB() == "$external" && getSSLManager() &&
            getSSLManager()->getSSLConfiguration().isClusterMember(args.userName.getUser())) {
            uasserted(ErrorCodes::BadValue,
                      "Cannot create an x.509 user with a subjectname "
                      "that would be recognized as an internal "
                      "cluster member.");
        }
#endif

        BSONObjBuilder userObjBuilder;
        userObjBuilder.append(
            "_id", str::stream() << args.userName.getDB() << "." << args.userName.getUser());
        UUID::gen().appendToBuilder(&userObjBuilder, AuthorizationManager::USERID_FIELD_NAME);
        userObjBuilder.append(AuthorizationManager::USER_NAME_FIELD_NAME, args.userName.getUser());
        userObjBuilder.append(AuthorizationManager::USER_DB_FIELD_NAME, args.userName.getDB());

        ServiceContext* serviceContext = opCtx->getClient()->getServiceContext();
        AuthorizationManager* authzManager = AuthorizationManager::get(serviceContext);
        int authzVersion;
        status = authzManager->getAuthorizationVersion(opCtx, &authzVersion);
        uassertStatusOK(status);

        BSONObjBuilder credentialsBuilder(userObjBuilder.subobjStart("credentials"));
        status = buildCredentials(&credentialsBuilder, args);
        uassertStatusOK(status);
        credentialsBuilder.done();

        if (args.authenticationRestrictions && !args.authenticationRestrictions->isEmpty()) {
            credentialsBuilder.append("authenticationRestrictions",
                                      *args.authenticationRestrictions);
        }

        if (args.hasCustomData) {
            userObjBuilder.append("customData", args.customData);
        }

        userObjBuilder.append("roles", rolesVectorToBSONArray(args.roles));

        BSONObj userObj = userObjBuilder.obj();
        V2UserDocumentParser parser;
        status = parser.checkValidUserDocument(userObj);
        uassertStatusOK(status);

        stdx::lock_guard<stdx::mutex> lk(getAuthzDataMutex(serviceContext));

        status = requireWritableAuthSchema28SCRAM(opCtx, authzManager);
        uassertStatusOK(status);

        // Role existence has to be checked after acquiring the update lock
        for (size_t i = 0; i < args.roles.size(); ++i) {
            BSONObj ignored;
            status = authzManager->getRoleDescription(opCtx, args.roles[i], &ignored);
            uassertStatusOK(status);
        }

        audit::logCreateUser(Client::getCurrent(),
                             args.userName,
                             args.hasPassword,
                             args.hasCustomData ? &args.customData : NULL,
                             args.roles,
                             args.authenticationRestrictions);
        status = insertPrivilegeDocument(opCtx, userObj);
        uassertStatusOK(status);
        return true;
    }
    bool run(OperationContext* opCtx,
             const string& dbname,
             const BSONObj& cmdObj,
             BSONObjBuilder& result) {
        auth::CreateOrUpdateUserArgs args;
        Status status = auth::parseCreateOrUpdateUserCommands(cmdObj, "createUser", dbname, &args);
        uassertStatusOK(status);

        if (args.userName.getDB() == "local") {
            uasserted(ErrorCodes::BadValue, "Cannot create users in the local database");
        }

        if (!args.hasPassword && args.userName.getDB() != "$external") {
            uasserted(ErrorCodes::BadValue,
                      "Must provide a 'pwd' field for all user documents, except those"
                      " with '$external' as the user's source db");
        }

        if ((args.hasPassword) && args.userName.getDB() == "$external") {
            uasserted(ErrorCodes::BadValue,
                      "Cannot set the password for users defined on the '$external' "
                      "database");
        }

        if (!args.hasRoles) {
            uasserted(ErrorCodes::BadValue, "\"createUser\" command requires a \"roles\" array");
        }

#ifdef MONGO_CONFIG_SSL
        if (args.userName.getDB() == "$external" && getSSLManager() &&
            getSSLManager()->getSSLConfiguration().isClusterMember(args.userName.getUser())) {
            uasserted(ErrorCodes::BadValue,
                      "Cannot create an x.509 user with a subjectname "
                      "that would be recognized as an internal "
                      "cluster member.");
        }
#endif

        BSONObjBuilder userObjBuilder;
        userObjBuilder.append(
            "_id", str::stream() << args.userName.getDB() << "." << args.userName.getUser());
        UUID::gen().appendToBuilder(&userObjBuilder, AuthorizationManager::USERID_FIELD_NAME);
        userObjBuilder.append(AuthorizationManager::USER_NAME_FIELD_NAME, args.userName.getUser());
        userObjBuilder.append(AuthorizationManager::USER_DB_FIELD_NAME, args.userName.getDB());

        ServiceContext* serviceContext = opCtx->getClient()->getServiceContext();
        AuthorizationManager* authzManager = AuthorizationManager::get(serviceContext);
        int authzVersion;
        status = authzManager->getAuthorizationVersion(opCtx, &authzVersion);
        uassertStatusOK(status);

        BSONObjBuilder credentialsBuilder(userObjBuilder.subobjStart("credentials"));
        status = buildCredentials(&credentialsBuilder, args);
        uassertStatusOK(status);
        credentialsBuilder.done();

        if (args.authenticationRestrictions && !args.authenticationRestrictions->isEmpty()) {
            credentialsBuilder.append("authenticationRestrictions",
                                      *args.authenticationRestrictions);
        }

        if (args.hasCustomData) {
            userObjBuilder.append("customData", args.customData);
        }

        userObjBuilder.append("roles", rolesVectorToBSONArray(args.roles));

        BSONObj userObj = userObjBuilder.obj();
        V2UserDocumentParser parser;
        status = parser.checkValidUserDocument(userObj);
        uassertStatusOK(status);

        stdx::lock_guard<stdx::mutex> lk(getAuthzDataMutex(serviceContext));

        status = requireWritableAuthSchema28SCRAM(opCtx, authzManager);
        uassertStatusOK(status);

         
        for (size_t i = 0; i < args.roles.size(); ++i) {
            BSONObj ignored;
            status = authzManager->getRoleDescription(opCtx, args.roles[i], &ignored);
            uassertStatusOK(status);
        }

        audit::logCreateUser(Client::getCurrent(),
                             args.userName,
                             args.hasPassword,
                             args.hasCustomData ? &args.customData : NULL,
                             args.roles,
                             args.authenticationRestrictions);
        status = insertPrivilegeDocument(opCtx, userObj);
        uassertStatusOK(status);
        return true;
    }