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