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 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)
20 * The full grammar is documented in the parser in OSDCap.cc.
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
33 #include "include/types.h"
34 #include "OpRequest.h"
38 #include <boost/optional.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 class_allow
;
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
)) {}
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
);
100 // auid and pool_name/nspace are mutually exclusive
101 int64_t auid
= CEPH_AUTH_UID_DEFAULT
;
102 OSDCapPoolNamespace pool_namespace
;
103 std::string object_prefix
;
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
) {}
116 * check if given request parameters match our constraints
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
124 bool is_match(const std::string
& pool_name
, const std::string
& nspace_name
,
125 int64_t pool_auid
, const std::string
& object
) const;
126 bool is_match_all() const;
129 ostream
& operator<<(ostream
& out
, const OSDCapMatch
& m
);
132 struct OSDCapProfile
{
134 OSDCapPoolNamespace pool_namespace
;
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
) {
144 inline bool is_valid() const {
145 return !name
.empty();
149 ostream
& operator<<(ostream
& out
, const OSDCapProfile
& m
);
154 OSDCapProfile profile
;
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
;
161 OSDCapGrant(const OSDCapMatch
& m
, const OSDCapSpec
& s
) : match(m
), spec(s
) {}
162 OSDCapGrant(const OSDCapProfile
& profile
) : profile(profile
) {
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;
172 void expand_profile();
175 ostream
& operator<<(ostream
& out
, const OSDCapGrant
& g
);
179 std::vector
<OSDCapGrant
> grants
;
182 explicit OSDCap(std::vector
<OSDCapGrant
> g
) : grants(std::move(g
)) {}
184 bool allow_all() const;
185 void set_allow_all();
186 bool parse(const std::string
& str
, ostream
*err
=NULL
);
189 * check if we are capable of something
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.
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
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;
209 static inline ostream
& operator<<(ostream
& out
, const OSDCap
& cap
)
211 return out
<< "osdcap" << cap
.grants
;