]>
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) | |
16 | * "allow rwx auid foo" (which allows full access to listed auids) | |
17 | * "allow rwx pool foo" (which allows full access to listed pools) | |
18 | * "allow *" (which allows full access to EVERYTHING) | |
19 | * | |
20 | * The full grammar is documented in the parser in OSDCap.cc. | |
21 | * | |
22 | * The OSD assumes that anyone with * caps is an admin and has full | |
23 | * message permissions. This means that only the monitor and the OSDs | |
24 | * should get * | |
25 | */ | |
26 | ||
27 | #ifndef CEPH_OSDCAP_H | |
28 | #define CEPH_OSDCAP_H | |
29 | ||
30 | #include <ostream> | |
31 | using std::ostream; | |
32 | ||
33 | #include "include/types.h" | |
34 | #include "OpRequest.h" | |
35 | ||
c07f9fc5 FG |
36 | #include <list> |
37 | #include <vector> | |
38 | #include <boost/optional.hpp> | |
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; | |
66 | std::string class_allow; | |
67 | ||
68 | OSDCapSpec() : allow(0) {} | |
69 | explicit OSDCapSpec(osd_rwxa_t v) : allow(v) {} | |
70 | explicit OSDCapSpec(std::string n) : allow(0), class_name(std::move(n)) {} | |
71 | OSDCapSpec(std::string n, std::string a) : | |
72 | allow(0), class_name(std::move(n)), class_allow(std::move(a)) {} | |
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 | ||
7c673cae FG |
98 | |
99 | struct OSDCapMatch { | |
100 | // auid and pool_name/nspace are mutually exclusive | |
c07f9fc5 FG |
101 | int64_t auid = CEPH_AUTH_UID_DEFAULT; |
102 | OSDCapPoolNamespace pool_namespace; | |
7c673cae FG |
103 | std::string object_prefix; |
104 | ||
c07f9fc5 FG |
105 | OSDCapMatch() {} |
106 | OSDCapMatch(const OSDCapPoolNamespace& pns) : pool_namespace(pns) {} | |
107 | OSDCapMatch(const std::string& pl, const std::string& pre) | |
108 | : pool_namespace(pl), object_prefix(pre) {} | |
109 | OSDCapMatch(const std::string& pl, const std::string& ns, | |
110 | const std::string& pre) | |
111 | : pool_namespace(pl, ns), object_prefix(pre) {} | |
112 | OSDCapMatch(uint64_t auid, const std::string& pre) | |
113 | : auid(auid), object_prefix(pre) {} | |
7c673cae FG |
114 | |
115 | /** | |
116 | * check if given request parameters match our constraints | |
117 | * | |
118 | * @param pool_name pool name | |
119 | * @param nspace_name namespace name | |
120 | * @param pool_auid pool's auid | |
121 | * @param object object name | |
122 | * @return true if we match, false otherwise | |
123 | */ | |
c07f9fc5 FG |
124 | bool is_match(const std::string& pool_name, const std::string& nspace_name, |
125 | int64_t pool_auid, const std::string& object) const; | |
7c673cae FG |
126 | bool is_match_all() const; |
127 | }; | |
128 | ||
129 | ostream& operator<<(ostream& out, const OSDCapMatch& m); | |
130 | ||
131 | ||
c07f9fc5 FG |
132 | struct OSDCapProfile { |
133 | std::string name; | |
134 | OSDCapPoolNamespace pool_namespace; | |
135 | ||
136 | OSDCapProfile() { | |
137 | } | |
138 | OSDCapProfile(const std::string& name, | |
139 | const std::string& pool_name, | |
140 | const boost::optional<std::string>& nspace = boost::none) | |
141 | : name(name), pool_namespace(pool_name, nspace) { | |
142 | } | |
143 | ||
144 | inline bool is_valid() const { | |
145 | return !name.empty(); | |
146 | } | |
147 | }; | |
148 | ||
149 | ostream& operator<<(ostream& out, const OSDCapProfile& m); | |
150 | ||
7c673cae FG |
151 | struct OSDCapGrant { |
152 | OSDCapMatch match; | |
153 | OSDCapSpec spec; | |
c07f9fc5 FG |
154 | OSDCapProfile profile; |
155 | ||
156 | // explicit grants that a profile grant expands to; populated as | |
157 | // needed by expand_profile() and cached here. | |
158 | std::list<OSDCapGrant> profile_grants; | |
7c673cae FG |
159 | |
160 | OSDCapGrant() {} | |
c07f9fc5 FG |
161 | OSDCapGrant(const OSDCapMatch& m, const OSDCapSpec& s) : match(m), spec(s) {} |
162 | OSDCapGrant(const OSDCapProfile& profile) : profile(profile) { | |
163 | expand_profile(); | |
164 | } | |
165 | ||
166 | bool allow_all() const; | |
167 | bool is_capable(const string& pool_name, const string& ns, int64_t pool_auid, | |
168 | const string& object, bool op_may_read, bool op_may_write, | |
169 | const std::vector<OpRequest::ClassInfo>& classes, | |
170 | std::vector<bool>* class_allowed) const; | |
171 | ||
172 | void expand_profile(); | |
7c673cae FG |
173 | }; |
174 | ||
175 | ostream& operator<<(ostream& out, const OSDCapGrant& g); | |
176 | ||
177 | ||
178 | struct OSDCap { | |
179 | std::vector<OSDCapGrant> grants; | |
180 | ||
181 | OSDCap() {} | |
182 | explicit OSDCap(std::vector<OSDCapGrant> g) : grants(std::move(g)) {} | |
183 | ||
184 | bool allow_all() const; | |
185 | void set_allow_all(); | |
186 | bool parse(const std::string& str, ostream *err=NULL); | |
187 | ||
188 | /** | |
189 | * check if we are capable of something | |
190 | * | |
191 | * This method actually checks a description of a particular operation against | |
192 | * what the capability has specified. Currently that is just rwx with matches | |
193 | * against pool, pool auid, and object name prefix. | |
194 | * | |
195 | * @param pool_name name of the pool we are accessing | |
196 | * @param ns name of the namespace we are accessing | |
197 | * @param pool_auid owner of the pool we are accessing | |
198 | * @param object name of the object we are accessing | |
199 | * @param op_may_read whether the operation may need to read | |
200 | * @param op_may_write whether the operation may need to write | |
201 | * @param classes (class-name, rd, wr, whitelisted-flag) tuples | |
202 | * @return true if the operation is allowed, false otherwise | |
203 | */ | |
204 | bool is_capable(const string& pool_name, const string& ns, int64_t pool_auid, | |
205 | const string& object, bool op_may_read, bool op_may_write, | |
206 | const std::vector<OpRequest::ClassInfo>& classes) const; | |
207 | }; | |
208 | ||
209 | static inline ostream& operator<<(ostream& out, const OSDCap& cap) | |
210 | { | |
211 | return out << "osdcap" << cap.grants; | |
212 | } | |
213 | ||
214 | #endif |