]> git.proxmox.com Git - ceph.git/blob - ceph/src/mds/MDSAuthCaps.h
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / mds / MDSAuthCaps.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2014 Red Hat
7 *
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.
12 *
13 */
14 #ifndef MDS_AUTH_CAPS_H
15 #define MDS_AUTH_CAPS_H
16
17 #include <ostream>
18 #include <string>
19 #include <string_view>
20 #include <vector>
21
22 #include "include/common_fwd.h"
23 #include "include/types.h"
24 #include "common/debug.h"
25
26 #include "mdstypes.h"
27
28 // unix-style capabilities
29 enum {
30 MAY_READ = (1 << 0),
31 MAY_WRITE = (1 << 1),
32 MAY_EXECUTE = (1 << 2),
33 MAY_CHOWN = (1 << 4),
34 MAY_CHGRP = (1 << 5),
35 MAY_SET_VXATTR = (1 << 6),
36 MAY_SNAPSHOT = (1 << 7),
37 };
38
39 // what we can do
40 struct MDSCapSpec {
41 static const unsigned ALL = (1 << 0);
42 static const unsigned READ = (1 << 1);
43 static const unsigned WRITE = (1 << 2);
44 // if the capability permits setting vxattrs (layout, quota, etc)
45 static const unsigned SET_VXATTR = (1 << 3);
46 // if the capability permits mksnap/rmsnap
47 static const unsigned SNAPSHOT = (1 << 4);
48
49 static const unsigned RW = (READ|WRITE);
50 static const unsigned RWP = (READ|WRITE|SET_VXATTR);
51 static const unsigned RWS = (READ|WRITE|SNAPSHOT);
52 static const unsigned RWPS = (READ|WRITE|SET_VXATTR|SNAPSHOT);
53
54 MDSCapSpec() = default;
55 MDSCapSpec(unsigned _caps) : caps(_caps) {
56 if (caps & ALL)
57 caps |= RWPS;
58 }
59
60 bool allow_all() const {
61 return (caps & ALL);
62 }
63 bool allow_read() const {
64 return (caps & READ);
65 }
66 bool allow_write() const {
67 return (caps & WRITE);
68 }
69
70 bool allows(bool r, bool w) const {
71 if (allow_all())
72 return true;
73 if (r && !allow_read())
74 return false;
75 if (w && !allow_write())
76 return false;
77 return true;
78 }
79
80 bool allow_snapshot() const {
81 return (caps & SNAPSHOT);
82 }
83 bool allow_set_vxattr() const {
84 return (caps & SET_VXATTR);
85 }
86 private:
87 unsigned caps = 0;
88 };
89
90 // conditions before we are allowed to do it
91 struct MDSCapMatch {
92 static const int64_t MDS_AUTH_UID_ANY = -1;
93
94 MDSCapMatch() : uid(MDS_AUTH_UID_ANY), fs_name(std::string()) {}
95
96 MDSCapMatch(int64_t uid_, std::vector<gid_t>& gids_) :
97 uid(uid_), gids(gids_), fs_name(std::string()) {}
98
99 explicit MDSCapMatch(const std::string &path_)
100 : uid(MDS_AUTH_UID_ANY), path(path_), fs_name(std::string()) {
101 normalize_path();
102 }
103
104 explicit MDSCapMatch(std::string path, std::string fs_name) :
105 uid(MDS_AUTH_UID_ANY), path(std::move(path)), fs_name(std::move(fs_name))
106 {
107 normalize_path();
108 }
109
110 explicit MDSCapMatch(std::string path, std::string fs_name, bool root_squash_) :
111 uid(MDS_AUTH_UID_ANY), path(std::move(path)), fs_name(std::move(fs_name)), root_squash(root_squash_)
112 {
113 normalize_path();
114 }
115
116 MDSCapMatch(const std::string& path_, int64_t uid_, std::vector<gid_t>& gids_)
117 : uid(uid_), gids(gids_), path(path_), fs_name(std::string()) {
118 normalize_path();
119 }
120
121 void normalize_path();
122
123 bool is_match_all() const
124 {
125 return uid == MDS_AUTH_UID_ANY && path == "";
126 }
127
128 // check whether this grant matches against a given file and caller uid:gid
129 bool match(std::string_view target_path,
130 const int caller_uid,
131 const int caller_gid,
132 const std::vector<uint64_t> *caller_gid_list) const;
133
134 /**
135 * Check whether this path *might* be accessible (actual permission
136 * depends on the stronger check in match()).
137 *
138 * @param target_path filesystem path without leading '/'
139 */
140 bool match_path(std::string_view target_path) const;
141
142 int64_t uid; // Require UID to be equal to this, if !=MDS_AUTH_UID_ANY
143 std::vector<gid_t> gids; // Use these GIDs
144 std::string path; // Require path to be child of this (may be "" or "/" for any)
145 std::string fs_name;
146 bool root_squash=false;
147 };
148
149 struct MDSCapGrant {
150 MDSCapGrant(const MDSCapSpec &spec_, const MDSCapMatch &match_,
151 boost::optional<std::string> n)
152 : spec(spec_), match(match_) {
153 if (n) {
154 network = *n;
155 parse_network();
156 }
157 }
158 MDSCapGrant() {}
159
160 void parse_network();
161
162 MDSCapSpec spec;
163 MDSCapMatch match;
164
165 std::string network;
166
167 entity_addr_t network_parsed;
168 unsigned network_prefix = 0;
169 bool network_valid = true;
170 };
171
172 class MDSAuthCaps
173 {
174 public:
175 MDSAuthCaps() = default;
176 explicit MDSAuthCaps(CephContext *cct_) : cct(cct_) {}
177
178 // this ctor is used by spirit/phoenix; doesn't need cct.
179 explicit MDSAuthCaps(const std::vector<MDSCapGrant>& grants_) : grants(grants_) {}
180
181 void clear() {
182 grants.clear();
183 }
184
185 void set_allow_all();
186 bool parse(CephContext *cct, std::string_view str, std::ostream *err);
187
188 bool allow_all() const;
189 bool is_capable(std::string_view inode_path,
190 uid_t inode_uid, gid_t inode_gid, unsigned inode_mode,
191 uid_t uid, gid_t gid, const std::vector<uint64_t> *caller_gid_list,
192 unsigned mask, uid_t new_uid, gid_t new_gid,
193 const entity_addr_t& addr) const;
194 bool path_capable(std::string_view inode_path) const;
195
196 bool fs_name_capable(std::string_view fs_name, unsigned mask) const {
197 if (allow_all()) {
198 return true;
199 }
200
201 for (const MDSCapGrant &g : grants) {
202 if (g.match.fs_name == fs_name || g.match.fs_name.empty() ||
203 g.match.fs_name == "*") {
204 if (mask & MAY_READ && g.spec.allow_read()) {
205 return true;
206 }
207
208 if (mask & MAY_WRITE && g.spec.allow_write()) {
209 return true;
210 }
211 }
212 }
213
214 return false;
215 }
216
217 friend std::ostream &operator<<(std::ostream &out, const MDSAuthCaps &cap);
218 private:
219 CephContext *cct = nullptr;
220 std::vector<MDSCapGrant> grants;
221 };
222
223 std::ostream &operator<<(std::ostream &out, const MDSCapMatch &match);
224 std::ostream &operator<<(std::ostream &out, const MDSCapSpec &spec);
225 std::ostream &operator<<(std::ostream &out, const MDSCapGrant &grant);
226 std::ostream &operator<<(std::ostream &out, const MDSAuthCaps &cap);
227
228 #endif // MDS_AUTH_CAPS_H