]>
Commit | Line | Data |
---|---|---|
c07f9fc5 | 1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
7c673cae FG |
2 | // vim: ts=8 sw=2 smarttab |
3 | /* | |
4 | * Ceph - scalable distributed file system | |
5 | * | |
6 | * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> | |
7 | * | |
8 | * This is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU Lesser General Public | |
c07f9fc5 | 10 | * License version 2.1, as published by the Free Software |
7c673cae | 11 | * Foundation. See file COPYING. |
c07f9fc5 FG |
12 | * |
13 | * OSDCaps: Hold the capabilities associated with a single authenticated | |
7c673cae FG |
14 | * user key. These are specified by text strings of the form |
15 | * "allow r" (which allows reading anything on the OSD) | |
7c673cae FG |
16 | * "allow rwx pool foo" (which allows full access to listed pools) |
17 | * "allow *" (which allows full access to EVERYTHING) | |
18 | * | |
19 | * The full grammar is documented in the parser in OSDCap.cc. | |
20 | * | |
21 | * The OSD assumes that anyone with * caps is an admin and has full | |
22 | * message permissions. This means that only the monitor and the OSDs | |
23 | * should get * | |
24 | */ | |
25 | ||
26 | #ifndef CEPH_OSDCAP_H | |
27 | #define CEPH_OSDCAP_H | |
28 | ||
29 | #include <ostream> | |
30 | using std::ostream; | |
31 | ||
32 | #include "include/types.h" | |
33 | #include "OpRequest.h" | |
34 | ||
c07f9fc5 FG |
35 | #include <list> |
36 | #include <vector> | |
37 | #include <boost/optional.hpp> | |
11fdf7f2 | 38 | #include <boost/fusion/include/adapt_struct.hpp> |
c07f9fc5 | 39 | |
7c673cae FG |
40 | static const __u8 OSD_CAP_R = (1 << 1); // read |
41 | static const __u8 OSD_CAP_W = (1 << 2); // write | |
42 | static const __u8 OSD_CAP_CLS_R = (1 << 3); // class read | |
43 | static const __u8 OSD_CAP_CLS_W = (1 << 4); // class write | |
44 | static const __u8 OSD_CAP_X = (OSD_CAP_CLS_R | OSD_CAP_CLS_W); // execute | |
45 | static const __u8 OSD_CAP_ANY = 0xff; // * | |
46 | ||
47 | struct osd_rwxa_t { | |
48 | __u8 val; | |
49 | ||
50 | // cppcheck-suppress noExplicitConstructor | |
51 | osd_rwxa_t(__u8 v = 0) : val(v) {} | |
52 | osd_rwxa_t& operator=(__u8 v) { | |
53 | val = v; | |
54 | return *this; | |
55 | } | |
56 | operator __u8() const { | |
57 | return val; | |
58 | } | |
59 | }; | |
60 | ||
31f18b77 | 61 | ostream& operator<<(ostream& out, const osd_rwxa_t& p); |
7c673cae FG |
62 | |
63 | struct OSDCapSpec { | |
64 | osd_rwxa_t allow; | |
65 | std::string class_name; | |
11fdf7f2 | 66 | std::string method_name; |
7c673cae FG |
67 | |
68 | OSDCapSpec() : allow(0) {} | |
69 | explicit OSDCapSpec(osd_rwxa_t v) : allow(v) {} | |
11fdf7f2 TL |
70 | OSDCapSpec(std::string class_name, std::string method_name) |
71 | : allow(0), class_name(std::move(class_name)), | |
72 | method_name(std::move(method_name)) {} | |
7c673cae FG |
73 | |
74 | bool allow_all() const { | |
75 | return allow == OSD_CAP_ANY; | |
76 | } | |
77 | }; | |
78 | ||
79 | ostream& operator<<(ostream& out, const OSDCapSpec& s); | |
80 | ||
c07f9fc5 FG |
81 | struct OSDCapPoolNamespace { |
82 | std::string pool_name; | |
83 | boost::optional<std::string> nspace = boost::none; | |
84 | ||
85 | OSDCapPoolNamespace() { | |
86 | } | |
87 | OSDCapPoolNamespace(const std::string& pool_name, | |
88 | const boost::optional<std::string>& nspace = boost::none) | |
89 | : pool_name(pool_name), nspace(nspace) { | |
90 | } | |
91 | ||
92 | bool is_match(const std::string& pn, const std::string& ns) const; | |
93 | bool is_match_all() const; | |
94 | }; | |
95 | ||
96 | ostream& operator<<(ostream& out, const OSDCapPoolNamespace& pns); | |
97 | ||
11fdf7f2 TL |
98 | struct OSDCapPoolTag { |
99 | typedef std::map<std::string, std::map<std::string, std::string> > app_map_t; | |
100 | std::string application; | |
101 | std::string key; | |
102 | std::string value; | |
103 | ||
104 | OSDCapPoolTag () {} | |
105 | OSDCapPoolTag(const std::string& application, const std::string& key, | |
106 | const std::string& value) : | |
107 | application(application), key(key), value(value) {} | |
108 | ||
109 | bool is_match(const app_map_t& app_map) const; | |
110 | bool is_match_all() const; | |
111 | }; | |
112 | // adapt for parsing with boost::spirit::qi in OSDCapParser | |
113 | BOOST_FUSION_ADAPT_STRUCT(OSDCapPoolTag, | |
114 | (std::string, application) | |
115 | (std::string, key) | |
116 | (std::string, value)) | |
117 | ||
118 | ostream& operator<<(ostream& out, const OSDCapPoolTag& pt); | |
7c673cae FG |
119 | |
120 | struct OSDCapMatch { | |
11fdf7f2 | 121 | typedef std::map<std::string, std::map<std::string, std::string> > app_map_t; |
c07f9fc5 | 122 | OSDCapPoolNamespace pool_namespace; |
11fdf7f2 | 123 | OSDCapPoolTag pool_tag; |
7c673cae FG |
124 | std::string object_prefix; |
125 | ||
c07f9fc5 | 126 | OSDCapMatch() {} |
11fdf7f2 TL |
127 | explicit OSDCapMatch(const OSDCapPoolTag& pt) : pool_tag(pt) {} |
128 | explicit OSDCapMatch(const OSDCapPoolNamespace& pns) : pool_namespace(pns) {} | |
129 | OSDCapMatch(const OSDCapPoolNamespace& pns, const std::string& pre) | |
130 | : pool_namespace(pns), object_prefix(pre) {} | |
c07f9fc5 FG |
131 | OSDCapMatch(const std::string& pl, const std::string& pre) |
132 | : pool_namespace(pl), object_prefix(pre) {} | |
133 | OSDCapMatch(const std::string& pl, const std::string& ns, | |
134 | const std::string& pre) | |
135 | : pool_namespace(pl, ns), object_prefix(pre) {} | |
11fdf7f2 TL |
136 | OSDCapMatch(const std::string& dummy, const std::string& app, |
137 | const std::string& key, const std::string& val) | |
138 | : pool_tag(app, key, val) {} | |
139 | OSDCapMatch(const std::string& ns, const OSDCapPoolTag& pt) | |
140 | : pool_namespace("", ns), pool_tag(pt) {} | |
7c673cae FG |
141 | |
142 | /** | |
143 | * check if given request parameters match our constraints | |
144 | * | |
145 | * @param pool_name pool name | |
146 | * @param nspace_name namespace name | |
7c673cae FG |
147 | * @param object object name |
148 | * @return true if we match, false otherwise | |
149 | */ | |
c07f9fc5 | 150 | bool is_match(const std::string& pool_name, const std::string& nspace_name, |
11fdf7f2 TL |
151 | const app_map_t& app_map, |
152 | const std::string& object) const; | |
7c673cae FG |
153 | bool is_match_all() const; |
154 | }; | |
155 | ||
156 | ostream& operator<<(ostream& out, const OSDCapMatch& m); | |
157 | ||
158 | ||
c07f9fc5 FG |
159 | struct OSDCapProfile { |
160 | std::string name; | |
161 | OSDCapPoolNamespace pool_namespace; | |
162 | ||
163 | OSDCapProfile() { | |
164 | } | |
165 | OSDCapProfile(const std::string& name, | |
166 | const std::string& pool_name, | |
167 | const boost::optional<std::string>& nspace = boost::none) | |
168 | : name(name), pool_namespace(pool_name, nspace) { | |
169 | } | |
170 | ||
171 | inline bool is_valid() const { | |
172 | return !name.empty(); | |
173 | } | |
174 | }; | |
175 | ||
176 | ostream& operator<<(ostream& out, const OSDCapProfile& m); | |
177 | ||
7c673cae FG |
178 | struct OSDCapGrant { |
179 | OSDCapMatch match; | |
180 | OSDCapSpec spec; | |
c07f9fc5 | 181 | OSDCapProfile profile; |
f67539c2 | 182 | std::string network; |
11fdf7f2 TL |
183 | entity_addr_t network_parsed; |
184 | unsigned network_prefix = 0; | |
185 | bool network_valid = true; | |
c07f9fc5 FG |
186 | |
187 | // explicit grants that a profile grant expands to; populated as | |
188 | // needed by expand_profile() and cached here. | |
189 | std::list<OSDCapGrant> profile_grants; | |
7c673cae FG |
190 | |
191 | OSDCapGrant() {} | |
11fdf7f2 | 192 | OSDCapGrant(const OSDCapMatch& m, const OSDCapSpec& s, |
f67539c2 | 193 | boost::optional<std::string> n = {}) |
11fdf7f2 TL |
194 | : match(m), spec(s) { |
195 | if (n) { | |
196 | set_network(*n); | |
197 | } | |
198 | } | |
199 | explicit OSDCapGrant(const OSDCapProfile& profile, | |
f67539c2 | 200 | boost::optional<std::string> n = {}) |
11fdf7f2 TL |
201 | : profile(profile) { |
202 | if (n) { | |
203 | set_network(*n); | |
204 | } | |
c07f9fc5 FG |
205 | expand_profile(); |
206 | } | |
207 | ||
f67539c2 | 208 | void set_network(const std::string& n); |
11fdf7f2 | 209 | |
c07f9fc5 | 210 | bool allow_all() const; |
f67539c2 | 211 | bool is_capable(const std::string& pool_name, const std::string& ns, |
11fdf7f2 | 212 | const OSDCapPoolTag::app_map_t& application_metadata, |
f67539c2 | 213 | const std::string& object, bool op_may_read, bool op_may_write, |
9f95a23c | 214 | const std::vector<OpInfo::ClassInfo>& classes, |
11fdf7f2 | 215 | const entity_addr_t& addr, |
c07f9fc5 FG |
216 | std::vector<bool>* class_allowed) const; |
217 | ||
218 | void expand_profile(); | |
7c673cae FG |
219 | }; |
220 | ||
221 | ostream& operator<<(ostream& out, const OSDCapGrant& g); | |
222 | ||
223 | ||
224 | struct OSDCap { | |
225 | std::vector<OSDCapGrant> grants; | |
226 | ||
227 | OSDCap() {} | |
228 | explicit OSDCap(std::vector<OSDCapGrant> g) : grants(std::move(g)) {} | |
229 | ||
230 | bool allow_all() const; | |
231 | void set_allow_all(); | |
232 | bool parse(const std::string& str, ostream *err=NULL); | |
233 | ||
234 | /** | |
235 | * check if we are capable of something | |
236 | * | |
237 | * This method actually checks a description of a particular operation against | |
238 | * what the capability has specified. Currently that is just rwx with matches | |
11fdf7f2 | 239 | * against pool, and object name prefix. |
7c673cae FG |
240 | * |
241 | * @param pool_name name of the pool we are accessing | |
242 | * @param ns name of the namespace we are accessing | |
7c673cae FG |
243 | * @param object name of the object we are accessing |
244 | * @param op_may_read whether the operation may need to read | |
245 | * @param op_may_write whether the operation may need to write | |
f67539c2 | 246 | * @param classes (class-name, rd, wr, allowed-flag) tuples |
7c673cae FG |
247 | * @return true if the operation is allowed, false otherwise |
248 | */ | |
f67539c2 | 249 | bool is_capable(const std::string& pool_name, const std::string& ns, |
11fdf7f2 | 250 | const OSDCapPoolTag::app_map_t& application_metadata, |
f67539c2 | 251 | const std::string& object, bool op_may_read, bool op_may_write, |
9f95a23c | 252 | const std::vector<OpInfo::ClassInfo>& classes, |
11fdf7f2 | 253 | const entity_addr_t& addr) const; |
7c673cae FG |
254 | }; |
255 | ||
f67539c2 | 256 | inline std::ostream& operator<<(std::ostream& out, const OSDCap& cap) |
7c673cae FG |
257 | { |
258 | return out << "osdcap" << cap.grants; | |
259 | } | |
260 | ||
261 | #endif |