1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
13 * OSDCaps: Hold the capabilities associated with a single authenticated
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 pool foo" (which allows full access to listed pools)
17 * "allow *" (which allows full access to EVERYTHING)
19 * The full grammar is documented in the parser in OSDCap.cc.
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
32 #include "include/types.h"
33 #include "OpRequest.h"
37 #include <boost/optional.hpp>
38 #include <boost/fusion/include/adapt_struct.hpp>
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; // *
50 // cppcheck-suppress noExplicitConstructor
51 osd_rwxa_t(__u8 v
= 0) : val(v
) {}
52 osd_rwxa_t
& operator=(__u8 v
) {
56 operator __u8() const {
61 ostream
& operator<<(ostream
& out
, const osd_rwxa_t
& p
);
65 std::string class_name
;
66 std::string method_name
;
68 OSDCapSpec() : allow(0) {}
69 explicit OSDCapSpec(osd_rwxa_t v
) : allow(v
) {}
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
)) {}
74 bool allow_all() const {
75 return allow
== OSD_CAP_ANY
;
79 ostream
& operator<<(ostream
& out
, const OSDCapSpec
& s
);
81 struct OSDCapPoolNamespace
{
82 std::string pool_name
;
83 boost::optional
<std::string
> nspace
= boost::none
;
85 OSDCapPoolNamespace() {
87 OSDCapPoolNamespace(const std::string
& pool_name
,
88 const boost::optional
<std::string
>& nspace
= boost::none
)
89 : pool_name(pool_name
), nspace(nspace
) {
92 bool is_match(const std::string
& pn
, const std::string
& ns
) const;
93 bool is_match_all() const;
96 ostream
& operator<<(ostream
& out
, const OSDCapPoolNamespace
& pns
);
98 struct OSDCapPoolTag
{
99 typedef std::map
<std::string
, std::map
<std::string
, std::string
> > app_map_t
;
100 std::string application
;
105 OSDCapPoolTag(const std::string
& application
, const std::string
& key
,
106 const std::string
& value
) :
107 application(application
), key(key
), value(value
) {}
109 bool is_match(const app_map_t
& app_map
) const;
110 bool is_match_all() const;
112 // adapt for parsing with boost::spirit::qi in OSDCapParser
113 BOOST_FUSION_ADAPT_STRUCT(OSDCapPoolTag
,
114 (std::string
, application
)
116 (std::string
, value
))
118 ostream
& operator<<(ostream
& out
, const OSDCapPoolTag
& pt
);
121 typedef std::map
<std::string
, std::map
<std::string
, std::string
> > app_map_t
;
122 OSDCapPoolNamespace pool_namespace
;
123 OSDCapPoolTag pool_tag
;
124 std::string object_prefix
;
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
) {}
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
) {}
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
) {}
143 * check if given request parameters match our constraints
145 * @param pool_name pool name
146 * @param nspace_name namespace name
147 * @param object object name
148 * @return true if we match, false otherwise
150 bool is_match(const std::string
& pool_name
, const std::string
& nspace_name
,
151 const app_map_t
& app_map
,
152 const std::string
& object
) const;
153 bool is_match_all() const;
156 ostream
& operator<<(ostream
& out
, const OSDCapMatch
& m
);
159 struct OSDCapProfile
{
161 OSDCapPoolNamespace pool_namespace
;
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
) {
171 inline bool is_valid() const {
172 return !name
.empty();
176 ostream
& operator<<(ostream
& out
, const OSDCapProfile
& m
);
181 OSDCapProfile profile
;
183 entity_addr_t network_parsed
;
184 unsigned network_prefix
= 0;
185 bool network_valid
= true;
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
;
192 OSDCapGrant(const OSDCapMatch
& m
, const OSDCapSpec
& s
,
193 boost::optional
<std::string
> n
= {})
194 : match(m
), spec(s
) {
199 explicit OSDCapGrant(const OSDCapProfile
& profile
,
200 boost::optional
<std::string
> n
= {})
208 void set_network(const std::string
& n
);
210 bool allow_all() const;
211 bool is_capable(const std::string
& pool_name
, const std::string
& ns
,
212 const OSDCapPoolTag::app_map_t
& application_metadata
,
213 const std::string
& object
, bool op_may_read
, bool op_may_write
,
214 const std::vector
<OpInfo::ClassInfo
>& classes
,
215 const entity_addr_t
& addr
,
216 std::vector
<bool>* class_allowed
) const;
218 void expand_profile();
221 ostream
& operator<<(ostream
& out
, const OSDCapGrant
& g
);
225 std::vector
<OSDCapGrant
> grants
;
228 explicit OSDCap(std::vector
<OSDCapGrant
> g
) : grants(std::move(g
)) {}
230 bool allow_all() const;
231 void set_allow_all();
232 bool parse(const std::string
& str
, ostream
*err
=NULL
);
235 * check if we are capable of something
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
239 * against pool, and object name prefix.
241 * @param pool_name name of the pool we are accessing
242 * @param ns name of the namespace we are accessing
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
246 * @param classes (class-name, rd, wr, allowed-flag) tuples
247 * @return true if the operation is allowed, false otherwise
249 bool is_capable(const std::string
& pool_name
, const std::string
& ns
,
250 const OSDCapPoolTag::app_map_t
& application_metadata
,
251 const std::string
& object
, bool op_may_read
, bool op_may_write
,
252 const std::vector
<OpInfo::ClassInfo
>& classes
,
253 const entity_addr_t
& addr
) const;
256 inline std::ostream
& operator<<(std::ostream
& out
, const OSDCap
& cap
)
258 return out
<< "osdcap" << cap
.grants
;