]> git.proxmox.com Git - ceph.git/blame - ceph/src/mds/MDSAuthCaps.h
import ceph pacific 16.2.5
[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),
b3b6e05e 37 MAY_FULL = (1 << 8),
7c673cae
FG
38};
39
7c673cae
FG
40// what we can do
41struct MDSCapSpec {
11fdf7f2
TL
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);
b3b6e05e
TL
49 // if the capability permits to bypass osd full check
50 static const unsigned FULL = (1 << 5);
11fdf7f2
TL
51
52 static const unsigned RW = (READ|WRITE);
b3b6e05e 53 static const unsigned RWF = (READ|WRITE|FULL);
11fdf7f2
TL
54 static const unsigned RWP = (READ|WRITE|SET_VXATTR);
55 static const unsigned RWS = (READ|WRITE|SNAPSHOT);
b3b6e05e
TL
56 static const unsigned RWFP = (READ|WRITE|FULL|SET_VXATTR);
57 static const unsigned RWFS = (READ|WRITE|FULL|SNAPSHOT);
11fdf7f2 58 static const unsigned RWPS = (READ|WRITE|SET_VXATTR|SNAPSHOT);
b3b6e05e 59 static const unsigned RWFPS = (READ|WRITE|FULL|SET_VXATTR|SNAPSHOT);
11fdf7f2
TL
60
61 MDSCapSpec() = default;
62 MDSCapSpec(unsigned _caps) : caps(_caps) {
63 if (caps & ALL)
b3b6e05e 64 caps |= RWFPS;
11fdf7f2 65 }
7c673cae
FG
66
67 bool allow_all() const {
11fdf7f2
TL
68 return (caps & ALL);
69 }
70 bool allow_read() const {
71 return (caps & READ);
72 }
73 bool allow_write() const {
74 return (caps & WRITE);
7c673cae
FG
75 }
76
77 bool allows(bool r, bool w) const {
11fdf7f2 78 if (allow_all())
7c673cae 79 return true;
11fdf7f2 80 if (r && !allow_read())
7c673cae 81 return false;
11fdf7f2 82 if (w && !allow_write())
7c673cae
FG
83 return false;
84 return true;
85 }
86
11fdf7f2
TL
87 bool allow_snapshot() const {
88 return (caps & SNAPSHOT);
89 }
90 bool allow_set_vxattr() const {
91 return (caps & SET_VXATTR);
7c673cae 92 }
b3b6e05e
TL
93 bool allow_full() const {
94 return (caps & FULL);
95 }
11fdf7f2
TL
96private:
97 unsigned caps = 0;
7c673cae
FG
98};
99
100// conditions before we are allowed to do it
101struct MDSCapMatch {
102 static const int64_t MDS_AUTH_UID_ANY = -1;
103
f67539c2
TL
104 MDSCapMatch() : uid(MDS_AUTH_UID_ANY), fs_name(std::string()) {}
105
106 MDSCapMatch(int64_t uid_, std::vector<gid_t>& gids_) :
107 uid(uid_), gids(gids_), fs_name(std::string()) {}
108
11fdf7f2 109 explicit MDSCapMatch(const std::string &path_)
f67539c2
TL
110 : uid(MDS_AUTH_UID_ANY), path(path_), fs_name(std::string()) {
111 normalize_path();
112 }
113
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))
116 {
7c673cae
FG
117 normalize_path();
118 }
f67539c2
TL
119
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_)
122 {
123 normalize_path();
124 }
125
11fdf7f2 126 MDSCapMatch(const std::string& path_, int64_t uid_, std::vector<gid_t>& gids_)
f67539c2 127 : uid(uid_), gids(gids_), path(path_), fs_name(std::string()) {
7c673cae
FG
128 normalize_path();
129 }
130
131 void normalize_path();
132
133 bool is_match_all() const
134 {
135 return uid == MDS_AUTH_UID_ANY && path == "";
136 }
137
138 // check whether this grant matches against a given file and caller uid:gid
11fdf7f2 139 bool match(std::string_view target_path,
7c673cae
FG
140 const int caller_uid,
141 const int caller_gid,
f67539c2 142 const std::vector<uint64_t> *caller_gid_list) const;
7c673cae
FG
143
144 /**
145 * Check whether this path *might* be accessible (actual permission
146 * depends on the stronger check in match()).
147 *
148 * @param target_path filesystem path without leading '/'
149 */
11fdf7f2 150 bool match_path(std::string_view target_path) const;
9f95a23c
TL
151
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)
f67539c2
TL
155 std::string fs_name;
156 bool root_squash=false;
7c673cae
FG
157};
158
159struct MDSCapGrant {
11fdf7f2
TL
160 MDSCapGrant(const MDSCapSpec &spec_, const MDSCapMatch &match_,
161 boost::optional<std::string> n)
162 : spec(spec_), match(match_) {
163 if (n) {
164 network = *n;
165 parse_network();
166 }
167 }
7c673cae 168 MDSCapGrant() {}
11fdf7f2
TL
169
170 void parse_network();
9f95a23c
TL
171
172 MDSCapSpec spec;
173 MDSCapMatch match;
174
175 std::string network;
176
177 entity_addr_t network_parsed;
178 unsigned network_prefix = 0;
179 bool network_valid = true;
7c673cae
FG
180};
181
182class MDSAuthCaps
183{
7c673cae 184public:
11fdf7f2
TL
185 MDSAuthCaps() = default;
186 explicit MDSAuthCaps(CephContext *cct_) : cct(cct_) {}
7c673cae
FG
187
188 // this ctor is used by spirit/phoenix; doesn't need cct.
11fdf7f2
TL
189 explicit MDSAuthCaps(const std::vector<MDSCapGrant>& grants_) : grants(grants_) {}
190
191 void clear() {
192 grants.clear();
193 }
7c673cae
FG
194
195 void set_allow_all();
11fdf7f2 196 bool parse(CephContext *cct, std::string_view str, std::ostream *err);
7c673cae
FG
197
198 bool allow_all() const;
11fdf7f2 199 bool is_capable(std::string_view inode_path,
7c673cae 200 uid_t inode_uid, gid_t inode_gid, unsigned inode_mode,
f67539c2 201 uid_t uid, gid_t gid, const std::vector<uint64_t> *caller_gid_list,
11fdf7f2
TL
202 unsigned mask, uid_t new_uid, gid_t new_gid,
203 const entity_addr_t& addr) const;
204 bool path_capable(std::string_view inode_path) const;
7c673cae 205
f67539c2
TL
206 bool fs_name_capable(std::string_view fs_name, unsigned mask) const {
207 if (allow_all()) {
208 return true;
209 }
210
211 for (const MDSCapGrant &g : grants) {
212 if (g.match.fs_name == fs_name || g.match.fs_name.empty() ||
213 g.match.fs_name == "*") {
214 if (mask & MAY_READ && g.spec.allow_read()) {
215 return true;
216 }
217
218 if (mask & MAY_WRITE && g.spec.allow_write()) {
219 return true;
220 }
221 }
222 }
223
224 return false;
225 }
226
7c673cae 227 friend std::ostream &operator<<(std::ostream &out, const MDSAuthCaps &cap);
9f95a23c
TL
228private:
229 CephContext *cct = nullptr;
230 std::vector<MDSCapGrant> grants;
7c673cae
FG
231};
232
7c673cae
FG
233std::ostream &operator<<(std::ostream &out, const MDSCapMatch &match);
234std::ostream &operator<<(std::ostream &out, const MDSCapSpec &spec);
235std::ostream &operator<<(std::ostream &out, const MDSCapGrant &grant);
236std::ostream &operator<<(std::ostream &out, const MDSAuthCaps &cap);
237
238#endif // MDS_AUTH_CAPS_H