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) 2014 Red Hat
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.
14 #ifndef MDS_AUTH_CAPS_H
15 #define MDS_AUTH_CAPS_H
19 #include <string_view>
22 #include "include/common_fwd.h"
23 #include "include/types.h"
24 #include "common/debug.h"
28 // unix-style capabilities
32 MAY_EXECUTE
= (1 << 2),
35 MAY_SET_VXATTR
= (1 << 6),
36 MAY_SNAPSHOT
= (1 << 7),
42 static const unsigned ALL
= (1 << 0);
43 static const unsigned READ
= (1 << 1);
44 static const unsigned WRITE
= (1 << 2);
45 // if the capability permits setting vxattrs (layout, quota, etc)
46 static const unsigned SET_VXATTR
= (1 << 3);
47 // if the capability permits mksnap/rmsnap
48 static const unsigned SNAPSHOT
= (1 << 4);
49 // if the capability permits to bypass osd full check
50 static const unsigned FULL
= (1 << 5);
52 static const unsigned RW
= (READ
|WRITE
);
53 static const unsigned RWF
= (READ
|WRITE
|FULL
);
54 static const unsigned RWP
= (READ
|WRITE
|SET_VXATTR
);
55 static const unsigned RWS
= (READ
|WRITE
|SNAPSHOT
);
56 static const unsigned RWFP
= (READ
|WRITE
|FULL
|SET_VXATTR
);
57 static const unsigned RWFS
= (READ
|WRITE
|FULL
|SNAPSHOT
);
58 static const unsigned RWPS
= (READ
|WRITE
|SET_VXATTR
|SNAPSHOT
);
59 static const unsigned RWFPS
= (READ
|WRITE
|FULL
|SET_VXATTR
|SNAPSHOT
);
61 MDSCapSpec() = default;
62 MDSCapSpec(unsigned _caps
) : caps(_caps
) {
67 bool allow_all() const {
70 bool allow_read() const {
73 bool allow_write() const {
74 return (caps
& WRITE
);
77 bool allows(bool r
, bool w
) const {
80 if (r
&& !allow_read())
82 if (w
&& !allow_write())
87 bool allow_snapshot() const {
88 return (caps
& SNAPSHOT
);
90 bool allow_set_vxattr() const {
91 return (caps
& SET_VXATTR
);
93 bool allow_full() const {
100 // conditions before we are allowed to do it
102 static const int64_t MDS_AUTH_UID_ANY
= -1;
104 MDSCapMatch() : uid(MDS_AUTH_UID_ANY
), fs_name(std::string()) {}
106 MDSCapMatch(int64_t uid_
, std::vector
<gid_t
>& gids_
) :
107 uid(uid_
), gids(gids_
), fs_name(std::string()) {}
109 explicit MDSCapMatch(const std::string
&path_
)
110 : uid(MDS_AUTH_UID_ANY
), path(path_
), fs_name(std::string()) {
114 explicit MDSCapMatch(std::string path
, std::string fs_name
) :
115 uid(MDS_AUTH_UID_ANY
), path(std::move(path
)), fs_name(std::move(fs_name
))
120 explicit MDSCapMatch(std::string path
, std::string fs_name
, bool root_squash_
) :
121 uid(MDS_AUTH_UID_ANY
), path(std::move(path
)), fs_name(std::move(fs_name
)), root_squash(root_squash_
)
126 MDSCapMatch(const std::string
& path_
, int64_t uid_
, std::vector
<gid_t
>& gids_
)
127 : uid(uid_
), gids(gids_
), path(path_
), fs_name(std::string()) {
131 void normalize_path();
133 bool is_match_all() const
135 return uid
== MDS_AUTH_UID_ANY
&& path
== "";
138 // check whether this grant matches against a given file and caller uid:gid
139 bool match(std::string_view target_path
,
140 const int caller_uid
,
141 const int caller_gid
,
142 const std::vector
<uint64_t> *caller_gid_list
) const;
145 * Check whether this path *might* be accessible (actual permission
146 * depends on the stronger check in match()).
148 * @param target_path filesystem path without leading '/'
150 bool match_path(std::string_view target_path
) const;
152 int64_t uid
; // Require UID to be equal to this, if !=MDS_AUTH_UID_ANY
153 std::vector
<gid_t
> gids
; // Use these GIDs
154 std::string path
; // Require path to be child of this (may be "" or "/" for any)
156 bool root_squash
=false;
160 MDSCapGrant(const MDSCapSpec
&spec_
, const MDSCapMatch
&match_
,
161 boost::optional
<std::string
> n
)
162 : spec(spec_
), match(match_
) {
170 void parse_network();
177 entity_addr_t network_parsed
;
178 unsigned network_prefix
= 0;
179 bool network_valid
= true;
185 MDSAuthCaps() = default;
187 // this ctor is used by spirit/phoenix
188 explicit MDSAuthCaps(const std::vector
<MDSCapGrant
>& grants_
) : grants(grants_
) {}
194 void set_allow_all();
195 bool parse(std::string_view str
, std::ostream
*err
);
197 bool allow_all() const;
198 bool is_capable(std::string_view inode_path
,
199 uid_t inode_uid
, gid_t inode_gid
, unsigned inode_mode
,
200 uid_t uid
, gid_t gid
, const std::vector
<uint64_t> *caller_gid_list
,
201 unsigned mask
, uid_t new_uid
, gid_t new_gid
,
202 const entity_addr_t
& addr
) const;
203 bool path_capable(std::string_view inode_path
) const;
205 bool fs_name_capable(std::string_view fs_name
, unsigned mask
) const {
210 for (const MDSCapGrant
&g
: grants
) {
211 if (g
.match
.fs_name
== fs_name
|| g
.match
.fs_name
.empty() ||
212 g
.match
.fs_name
== "*") {
213 if (mask
& MAY_READ
&& g
.spec
.allow_read()) {
217 if (mask
& MAY_WRITE
&& g
.spec
.allow_write()) {
226 friend std::ostream
&operator<<(std::ostream
&out
, const MDSAuthCaps
&cap
);
228 std::vector
<MDSCapGrant
> grants
;
231 std::ostream
&operator<<(std::ostream
&out
, const MDSCapMatch
&match
);
232 std::ostream
&operator<<(std::ostream
&out
, const MDSCapSpec
&spec
);
233 std::ostream
&operator<<(std::ostream
&out
, const MDSCapGrant
&grant
);
234 std::ostream
&operator<<(std::ostream
&out
, const MDSAuthCaps
&cap
);
236 #endif // MDS_AUTH_CAPS_H