]> git.proxmox.com Git - ceph.git/blame - ceph/src/rgw/rgw_acl.cc
update sources to v12.1.0
[ceph.git] / ceph / src / rgw / rgw_acl.cc
CommitLineData
7c673cae
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3
4#include <string.h>
5
6#include <iostream>
7#include <map>
8
9#include "include/types.h"
10
11#include "common/Formatter.h"
12
13#include "rgw_acl.h"
14#include "rgw_user.h"
15
16#define dout_subsys ceph_subsys_rgw
17
18using namespace std;
19
20void RGWAccessControlList::_add_grant(ACLGrant *grant)
21{
22 ACLPermission& perm = grant->get_permission();
23 ACLGranteeType& type = grant->get_type();
24 switch (type.get_type()) {
25 case ACL_TYPE_REFERER:
26 referer_list.emplace_back(grant->get_referer(), perm.get_permissions());
31f18b77
FG
27
28 /* We're specially handling the Swift's .r:* as the S3 API has a similar
29 * concept and thus we can have a small portion of compatibility here. */
30 if (grant->get_referer() == RGW_REFERER_WILDCARD) {
31 acl_group_map[ACL_GROUP_ALL_USERS] |= perm.get_permissions();
32 }
7c673cae
FG
33 break;
34 case ACL_TYPE_GROUP:
35 acl_group_map[grant->get_group()] |= perm.get_permissions();
36 break;
37 default:
38 {
39 rgw_user id;
40 if (!grant->get_id(id)) {
41 ldout(cct, 0) << "ERROR: grant->get_id() failed" << dendl;
42 }
43 acl_user_map[id.to_str()] |= perm.get_permissions();
44 }
45 }
46}
47
48void RGWAccessControlList::add_grant(ACLGrant *grant)
49{
50 rgw_user id;
51 grant->get_id(id); // not that this will return false for groups, but that's ok, we won't search groups
52 grant_map.insert(pair<string, ACLGrant>(id.to_str(), *grant));
53 _add_grant(grant);
54}
55
56uint32_t RGWAccessControlList::get_perm(const rgw::auth::Identity& auth_identity,
57 const uint32_t perm_mask)
58{
59 ldout(cct, 5) << "Searching permissions for identity=" << auth_identity
60 << " mask=" << perm_mask << dendl;
61
62 return perm_mask & auth_identity.get_perms_from_aclspec(acl_user_map);
63}
64
65uint32_t RGWAccessControlList::get_group_perm(ACLGroupTypeEnum group,
66 const uint32_t perm_mask)
67{
68 ldout(cct, 5) << "Searching permissions for group=" << (int)group
69 << " mask=" << perm_mask << dendl;
70
71 const auto iter = acl_group_map.find((uint32_t)group);
72 if (iter != acl_group_map.end()) {
73 ldout(cct, 5) << "Found permission: " << iter->second << dendl;
74 return iter->second & perm_mask;
75 }
76 ldout(cct, 5) << "Permissions for group not found" << dendl;
77 return 0;
78}
79
31f18b77
FG
80uint32_t RGWAccessControlList::get_referer_perm(const uint32_t current_perm,
81 const std::string http_referer,
7c673cae
FG
82 const uint32_t perm_mask)
83{
84 ldout(cct, 5) << "Searching permissions for referer=" << http_referer
85 << " mask=" << perm_mask << dendl;
86
31f18b77
FG
87 /* This function is bacically a transformation from current perm to
88 * a new one that takes into consideration the Swift's HTTP referer-
89 * based ACLs. We need to go through all items to respect negative
90 * grants. */
91 uint32_t referer_perm = current_perm;
92 for (const auto& r : referer_list) {
93 if (r.is_match(http_referer)) {
94 referer_perm = r.perm;
7c673cae 95 }
7c673cae 96 }
31f18b77
FG
97
98 ldout(cct, 5) << "Found referer permission=" << referer_perm << dendl;
99 return referer_perm & perm_mask;
7c673cae
FG
100}
101
102uint32_t RGWAccessControlPolicy::get_perm(const rgw::auth::Identity& auth_identity,
103 const uint32_t perm_mask,
104 const char * const http_referer)
105{
106 ldout(cct, 20) << "-- Getting permissions begin with perm_mask=" << perm_mask
107 << dendl;
108
109 uint32_t perm = acl.get_perm(auth_identity, perm_mask);
110
111 if (auth_identity.is_owner_of(owner.get_id())) {
112 perm |= perm_mask & (RGW_PERM_READ_ACP | RGW_PERM_WRITE_ACP);
113 }
114
115 if (perm == perm_mask) {
116 return perm;
117 }
118
119 /* should we continue looking up? */
120 if ((perm & perm_mask) != perm_mask) {
121 perm |= acl.get_group_perm(ACL_GROUP_ALL_USERS, perm_mask);
122
123 if (false == auth_identity.is_owner_of(rgw_user(RGW_USER_ANON_ID))) {
124 /* this is not the anonymous user */
125 perm |= acl.get_group_perm(ACL_GROUP_AUTHENTICATED_USERS, perm_mask);
126 }
127 }
128
129 /* Should we continue looking up even deeper? */
130 if (nullptr != http_referer && (perm & perm_mask) != perm_mask) {
31f18b77 131 perm = acl.get_referer_perm(perm, http_referer, perm_mask);
7c673cae
FG
132 }
133
134 ldout(cct, 5) << "-- Getting permissions done for identity=" << auth_identity
135 << ", owner=" << owner.get_id()
136 << ", perm=" << perm << dendl;
137
138 return perm;
139}
140
141bool RGWAccessControlPolicy::verify_permission(const rgw::auth::Identity& auth_identity,
142 const uint32_t user_perm_mask,
143 const uint32_t perm,
144 const char * const http_referer)
145{
146 uint32_t test_perm = perm | RGW_PERM_READ_OBJS | RGW_PERM_WRITE_OBJS;
147
148 uint32_t policy_perm = get_perm(auth_identity, test_perm, http_referer);
149
150 /* the swift WRITE_OBJS perm is equivalent to the WRITE obj, just
151 convert those bits. Note that these bits will only be set on
152 buckets, so the swift READ permission on bucket will allow listing
153 the bucket content */
154 if (policy_perm & RGW_PERM_WRITE_OBJS) {
155 policy_perm |= (RGW_PERM_WRITE | RGW_PERM_WRITE_ACP);
156 }
157 if (policy_perm & RGW_PERM_READ_OBJS) {
158 policy_perm |= (RGW_PERM_READ | RGW_PERM_READ_ACP);
159 }
160
161 uint32_t acl_perm = policy_perm & perm & user_perm_mask;
162
163 ldout(cct, 10) << " identity=" << auth_identity
164 << " requested perm (type)=" << perm
165 << ", policy perm=" << policy_perm
166 << ", user_perm_mask=" << user_perm_mask
167 << ", acl perm=" << acl_perm << dendl;
168
169 return (perm == acl_perm);
170}
171
172