]> git.proxmox.com Git - ceph.git/blame - ceph/src/mds/MDSAuthCaps.h
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / mds / MDSAuthCaps.h
CommitLineData
7c673cae
FG
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 */
7c673cae
FG
14#ifndef MDS_AUTH_CAPS_H
15#define MDS_AUTH_CAPS_H
16
f67539c2 17#include <ostream>
94b18763 18#include <string>
11fdf7f2 19#include <string_view>
94b18763
FG
20#include <vector>
21
9f95a23c 22#include "include/common_fwd.h"
7c673cae
FG
23#include "include/types.h"
24#include "common/debug.h"
25
f67539c2
TL
26#include "mdstypes.h"
27
7c673cae
FG
28// unix-style capabilities
29enum {
11fdf7f2
TL
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),
7c673cae
FG
37};
38
7c673cae
FG
39// what we can do
40struct MDSCapSpec {
11fdf7f2
TL
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 }
7c673cae
FG
59
60 bool allow_all() const {
11fdf7f2
TL
61 return (caps & ALL);
62 }
63 bool allow_read() const {
64 return (caps & READ);
65 }
66 bool allow_write() const {
67 return (caps & WRITE);
7c673cae
FG
68 }
69
70 bool allows(bool r, bool w) const {
11fdf7f2 71 if (allow_all())
7c673cae 72 return true;
11fdf7f2 73 if (r && !allow_read())
7c673cae 74 return false;
11fdf7f2 75 if (w && !allow_write())
7c673cae
FG
76 return false;
77 return true;
78 }
79
11fdf7f2
TL
80 bool allow_snapshot() const {
81 return (caps & SNAPSHOT);
82 }
83 bool allow_set_vxattr() const {
84 return (caps & SET_VXATTR);
7c673cae 85 }
11fdf7f2
TL
86private:
87 unsigned caps = 0;
7c673cae
FG
88};
89
90// conditions before we are allowed to do it
91struct MDSCapMatch {
92 static const int64_t MDS_AUTH_UID_ANY = -1;
93
f67539c2
TL
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
11fdf7f2 99 explicit MDSCapMatch(const std::string &path_)
f67539c2
TL
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 {
7c673cae
FG
107 normalize_path();
108 }
f67539c2
TL
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
11fdf7f2 116 MDSCapMatch(const std::string& path_, int64_t uid_, std::vector<gid_t>& gids_)
f67539c2 117 : uid(uid_), gids(gids_), path(path_), fs_name(std::string()) {
7c673cae
FG
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
11fdf7f2 129 bool match(std::string_view target_path,
7c673cae
FG
130 const int caller_uid,
131 const int caller_gid,
f67539c2 132 const std::vector<uint64_t> *caller_gid_list) const;
7c673cae
FG
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 */
11fdf7f2 140 bool match_path(std::string_view target_path) const;
9f95a23c
TL
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)
f67539c2
TL
145 std::string fs_name;
146 bool root_squash=false;
7c673cae
FG
147};
148
149struct MDSCapGrant {
11fdf7f2
TL
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 }
7c673cae 158 MDSCapGrant() {}
11fdf7f2
TL
159
160 void parse_network();
9f95a23c
TL
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;
7c673cae
FG
170};
171
172class MDSAuthCaps
173{
7c673cae 174public:
11fdf7f2
TL
175 MDSAuthCaps() = default;
176 explicit MDSAuthCaps(CephContext *cct_) : cct(cct_) {}
7c673cae
FG
177
178 // this ctor is used by spirit/phoenix; doesn't need cct.
11fdf7f2
TL
179 explicit MDSAuthCaps(const std::vector<MDSCapGrant>& grants_) : grants(grants_) {}
180
181 void clear() {
182 grants.clear();
183 }
7c673cae
FG
184
185 void set_allow_all();
11fdf7f2 186 bool parse(CephContext *cct, std::string_view str, std::ostream *err);
7c673cae
FG
187
188 bool allow_all() const;
11fdf7f2 189 bool is_capable(std::string_view inode_path,
7c673cae 190 uid_t inode_uid, gid_t inode_gid, unsigned inode_mode,
f67539c2 191 uid_t uid, gid_t gid, const std::vector<uint64_t> *caller_gid_list,
11fdf7f2
TL
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;
7c673cae 195
f67539c2
TL
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
7c673cae 217 friend std::ostream &operator<<(std::ostream &out, const MDSAuthCaps &cap);
9f95a23c
TL
218private:
219 CephContext *cct = nullptr;
220 std::vector<MDSCapGrant> grants;
7c673cae
FG
221};
222
7c673cae
FG
223std::ostream &operator<<(std::ostream &out, const MDSCapMatch &match);
224std::ostream &operator<<(std::ostream &out, const MDSCapSpec &spec);
225std::ostream &operator<<(std::ostream &out, const MDSCapGrant &grant);
226std::ostream &operator<<(std::ostream &out, const MDSAuthCaps &cap);
227
228#endif // MDS_AUTH_CAPS_H