--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab ft=cpp
+
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright contributors to the Ceph project
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#include "rgw_iam_managed_policy.h"
+#include "rgw_iam_policy.h"
+
+namespace rgw::IAM {
+
+// Type: AWS managed policy
+// Creation time: February 06, 2015, 18:40 UTC
+// Edited time: June 21, 2019, 19:40 UTC
+// ARN: arn:aws:iam::aws:policy/IAMFullAccess
+// Policy version: v2 (default)
+static constexpr std::string_view IAMFullAccess = R"(
+{
+ "Version" : "2012-10-17",
+ "Statement" : [
+ {
+ "Effect" : "Allow",
+ "Action" : [
+ "iam:*",
+ "organizations:DescribeAccount",
+ "organizations:DescribeOrganization",
+ "organizations:DescribeOrganizationalUnit",
+ "organizations:DescribePolicy",
+ "organizations:ListChildren",
+ "organizations:ListParents",
+ "organizations:ListPoliciesForTarget",
+ "organizations:ListRoots",
+ "organizations:ListPolicies",
+ "organizations:ListTargetsForPolicy"
+ ],
+ "Resource" : "*"
+ }
+ ]
+})";
+
+// Type: AWS managed policy
+// Creation time: February 06, 2015, 18:40 UTC
+// Edited time: January 25, 2018, 19:11 UTC
+// ARN: arn:aws:iam::aws:policy/IAMReadOnlyAccess
+// Policy version: v4 (default)
+static constexpr std::string_view IAMReadOnlyAccess = R"(
+{
+ "Version" : "2012-10-17",
+ "Statement" : [
+ {
+ "Effect" : "Allow",
+ "Action" : [
+ "iam:GenerateCredentialReport",
+ "iam:GenerateServiceLastAccessedDetails",
+ "iam:Get*",
+ "iam:List*",
+ "iam:SimulateCustomPolicy",
+ "iam:SimulatePrincipalPolicy"
+ ],
+ "Resource" : "*"
+ }
+ ]
+})";
+
+// Type: AWS managed policy
+// Creation time: February 06, 2015, 18:41 UTC
+// Edited time: February 06, 2015, 18:41 UTC
+// ARN: arn:aws:iam::aws:policy/AmazonSNSFullAccess
+// Policy version: v1 (default)
+static constexpr std::string_view AmazonSNSFullAccess = R"(
+{
+ "Version" : "2012-10-17",
+ "Statement" : [
+ {
+ "Action" : [
+ "sns:*"
+ ],
+ "Effect" : "Allow",
+ "Resource" : "*"
+ }
+ ]
+})";
+
+// Type: AWS managed policy
+// Creation time: February 06, 2015, 18:41 UTC
+// Edited time: February 06, 2015, 18:41 UTC
+// ARN: arn:aws:iam::aws:policy/AmazonSNSReadOnlyAccess
+// Policy version: v1 (default)
+static constexpr std::string_view AmazonSNSReadOnlyAccess = R"(
+{
+ "Version" : "2012-10-17",
+ "Statement" : [
+ {
+ "Effect" : "Allow",
+ "Action" : [
+ "sns:GetTopicAttributes",
+ "sns:List*"
+ ],
+ "Resource" : "*"
+ }
+ ]
+})";
+
+// Type: AWS managed policy
+// Creation time: February 06, 2015, 18:40 UTC
+// Edited time: September 27, 2021, 20:16 UTC
+// ARN: arn:aws:iam::aws:policy/AmazonS3FullAccess
+// Policy version: v2 (default)
+static constexpr std::string_view AmazonS3FullAccess = R"(
+{
+ "Version" : "2012-10-17",
+ "Statement" : [
+ {
+ "Effect" : "Allow",
+ "Action" : [
+ "s3:*",
+ "s3-object-lambda:*"
+ ],
+ "Resource" : "*"
+ }
+ ]
+})";
+
+// Type: AWS managed policy
+// Creation time: February 06, 2015, 18:40 UTC
+// Edited time: August 10, 2023, 21:31 UTC
+// ARN: arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
+// Policy version: v3 (default)
+static constexpr std::string_view AmazonS3ReadOnlyAccess = R"(
+{
+ "Version" : "2012-10-17",
+ "Statement" : [
+ {
+ "Effect" : "Allow",
+ "Action" : [
+ "s3:Get*",
+ "s3:List*",
+ "s3:Describe*",
+ "s3-object-lambda:Get*",
+ "s3-object-lambda:List*"
+ ],
+ "Resource" : "*"
+ }
+ ]
+})";
+
+auto get_managed_policy(CephContext* cct, std::string_view arn)
+ -> std::optional<Policy>
+{
+ const std::string tenant; // empty tenant
+ constexpr bool reject = false; // reject_invalid_principals
+ if (arn == "arn:aws:iam::aws:policy/IAMFullAccess") {
+ return Policy{cct, tenant, std::string{IAMFullAccess}, reject};
+ } else if (arn == "arn:aws:iam::aws:policy/IAMReadOnlyAccess") {
+ return Policy{cct, tenant, std::string{IAMReadOnlyAccess}, reject};
+ } else if (arn == "arn:aws:iam::aws:policy/AmazonSNSFullAccess") {
+ return Policy{cct, tenant, std::string{AmazonSNSFullAccess}, reject};
+ } else if (arn == "arn:aws:iam::aws:policy/AmazonSNSReadOnlyAccess") {
+ return Policy{cct, tenant, std::string{AmazonSNSReadOnlyAccess}, reject};
+ } else if (arn == "arn:aws:iam::aws:policy/AmazonS3FullAccess") {
+ return Policy{cct, tenant, std::string{AmazonS3FullAccess}, reject};
+ } else if (arn == "arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess") {
+ return Policy{cct, tenant, std::string{AmazonS3ReadOnlyAccess}, reject};
+ }
+ return {};
+}
+
+} // namespace rgw::IAM
*
*/
+#include "rgw_iam_policy.h"
+
#include <string>
#include <boost/intrusive_ptr.hpp>
#include "global/global_init.h"
#include "rgw_auth.h"
#include "rgw_auth_registry.h"
-#include "rgw_iam_policy.h"
+#include "rgw_iam_managed_policy.h"
#include "rgw_op.h"
#include "rgw_process_env.h"
#include "rgw_sal_rados.h"
using rgw::IAM::organizationsAllValue;
using rgw::IAM::allValue;
+using rgw::IAM::get_managed_policy;
+
class FakeIdentity : public Identity {
const Principal id;
public:
Effect::Pass);
}
+
+class ManagedPolicyTest : public ::testing::Test {
+protected:
+ intrusive_ptr<CephContext> cct;
+public:
+ ManagedPolicyTest() : cct(new CephContext(CEPH_ENTITY_TYPE_CLIENT)) {}
+};
+
+TEST_F(ManagedPolicyTest, IAMFullAccess)
+{
+ auto p = get_managed_policy(cct.get(), "arn:aws:iam::aws:policy/IAMFullAccess");
+ ASSERT_TRUE(p);
+
+ Action_t act = iamAllValue | organizationsAllValue;
+ act[iamAll] = 1;
+ act[organizationsAll] = 1;
+ EXPECT_EQ(act, p->statements[0].action);
+}
+
+TEST_F(ManagedPolicyTest, IAMReadOnlyAccess)
+{
+ auto p = get_managed_policy(cct.get(), "arn:aws:iam::aws:policy/IAMReadOnlyAccess");
+ ASSERT_TRUE(p);
+
+ Action_t act;
+ act[iamGenerateCredentialReport] = 1;
+ act[iamGenerateServiceLastAccessedDetails] = 1;
+ act[iamGetUserPolicy] = 1;
+ act[iamGetRole] = 1;
+ act[iamGetRolePolicy] = 1;
+ act[iamGetOIDCProvider] = 1;
+ act[iamGetUser] = 1;
+ act[iamListUserPolicies] = 1;
+ act[iamListRoles] = 1;
+ act[iamListRolePolicies] = 1;
+ act[iamListOIDCProviders] = 1;
+ act[iamListRoleTags] = 1;
+ act[iamListUsers] = 1;
+ act[iamListAccessKeys] = 1;
+ act[iamSimulateCustomPolicy] = 1;
+ act[iamSimulatePrincipalPolicy] = 1;
+
+ EXPECT_EQ(act, p->statements[0].action);
+}
+
+TEST_F(ManagedPolicyTest, AmazonSNSFullAccess)
+{
+ auto p = get_managed_policy(cct.get(), "arn:aws:iam::aws:policy/AmazonSNSFullAccess");
+ ASSERT_TRUE(p);
+
+ Action_t act = snsAllValue;
+ act[snsAll] = 1;
+ EXPECT_EQ(act, p->statements[0].action);
+}
+
+TEST_F(ManagedPolicyTest, AmazonSNSReadOnlyAccess)
+{
+ auto p = get_managed_policy(cct.get(), "arn:aws:iam::aws:policy/AmazonSNSReadOnlyAccess");
+ ASSERT_TRUE(p);
+
+ Action_t act;
+ // sns:GetTopicAttributes
+ act[snsGetTopicAttributes] = 1;
+ // sns:List*
+ act[snsListTopics] = 1;
+
+ EXPECT_EQ(act, p->statements[0].action);
+}
+
+TEST_F(ManagedPolicyTest, AmazonS3FullAccess)
+{
+ auto p = get_managed_policy(cct.get(), "arn:aws:iam::aws:policy/AmazonS3FullAccess");
+ ASSERT_TRUE(p);
+
+ Action_t act = s3AllValue | s3objectlambdaAllValue;
+ act[s3All] = 1;
+ act[s3objectlambdaAll] = 1;
+ EXPECT_EQ(act, p->statements[0].action);
+}
+
+TEST_F(ManagedPolicyTest, AmazonS3ReadOnlyAccess)
+{
+ auto p = get_managed_policy(cct.get(), "arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess");
+ ASSERT_TRUE(p);
+
+ Action_t act;
+ // s3:Get*
+ act[s3GetObject] = 1;
+ act[s3GetObjectVersion] = 1;
+ act[s3GetObjectAcl] = 1;
+ act[s3GetObjectVersionAcl] = 1;
+ act[s3GetObjectTorrent] = 1;
+ act[s3GetObjectVersionTorrent] = 1;
+ act[s3GetAccelerateConfiguration] = 1;
+ act[s3GetBucketAcl] = 1;
+ act[s3GetBucketOwnershipControls] = 1;
+ act[s3GetBucketCORS] = 1;
+ act[s3GetBucketVersioning] = 1;
+ act[s3GetBucketRequestPayment] = 1;
+ act[s3GetBucketLocation] = 1;
+ act[s3GetBucketPolicy] = 1;
+ act[s3GetBucketNotification] = 1;
+ act[s3GetBucketLogging] = 1;
+ act[s3GetBucketTagging] = 1;
+ act[s3GetBucketWebsite] = 1;
+ act[s3GetLifecycleConfiguration] = 1;
+ act[s3GetReplicationConfiguration] = 1;
+ act[s3GetObjectTagging] = 1;
+ act[s3GetObjectVersionTagging] = 1;
+ act[s3GetBucketObjectLockConfiguration] = 1;
+ act[s3GetObjectRetention] = 1;
+ act[s3GetObjectLegalHold] = 1;
+ act[s3GetBucketPolicyStatus] = 1;
+ act[s3GetPublicAccessBlock] = 1;
+ act[s3GetBucketPublicAccessBlock] = 1;
+ act[s3GetBucketEncryption] = 1;
+ // s3:List*
+ act[s3ListMultipartUploadParts] = 1;
+ act[s3ListBucket] = 1;
+ act[s3ListBucketVersions] = 1;
+ act[s3ListAllMyBuckets] = 1;
+ act[s3ListBucketMultipartUploads] = 1;
+ // s3:Describe*
+ act[s3DescribeJob] = 1;
+ // s3-object-lambda:Get*
+ act[s3objectlambdaGetObject] = 1;
+ // s3-object-lambda:List*
+ act[s3objectlambdaListBucket] = 1;
+ act[s3objectlambdaAll] = 1;
+
+ EXPECT_EQ(act, p->statements[0].action);
+}
+
const string PolicyTest::arbitrary_tenant = "arbitrary_tenant";
string PolicyTest::example1 = R"(
{