/
MDSAuthCaps.h
139 lines (111 loc) · 3.46 KB
/
MDSAuthCaps.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
/*
* Ceph - scalable distributed file system
*
* Copyright (C) 2014 Red Hat
*
* This is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software
* Foundation. See file COPYING.
*
*/
#ifndef MDS_AUTH_CAPS_H
#define MDS_AUTH_CAPS_H
#include <vector>
#include <string>
#include <sstream>
#include "include/types.h"
#include "common/debug.h"
// unix-style capabilities
enum {
MAY_READ = 1,
MAY_WRITE = 2,
MAY_EXECUTE = 4,
MAY_CHOWN = 16,
MAY_CHGRP = 32,
MAY_SET_POOL = 64,
};
class CephContext;
// what we can do
struct MDSCapSpec {
bool read, write, any;
// True if the capability permits modifying the pool on file layouts
bool layout_pool;
MDSCapSpec() : read(false), write(false), any(false), layout_pool(false) {}
MDSCapSpec(bool r, bool w, bool a, bool lop)
: read(r), write(w), any(a), layout_pool(lop) {}
bool allow_all() const {
return any;
}
bool allows(bool r, bool w) const {
if (any)
return true;
if (r && !read)
return false;
if (w && !write)
return false;
return true;
}
bool allows_set_pool() const {
return layout_pool;
}
};
// conditions before we are allowed to do it
struct MDSCapMatch {
static const int64_t MDS_AUTH_UID_ANY = -1;
int64_t uid; // Require UID to be equal to this, if !=MDS_AUTH_UID_ANY
std::vector<gid_t> gids; // Use these GIDs
std::string path; // Require path to be child of this (may be "" or "/" for any)
MDSCapMatch() : uid(MDS_AUTH_UID_ANY) {}
MDSCapMatch(int64_t uid_, std::vector<gid_t>& gids_) : uid(uid_), gids(gids_) {}
MDSCapMatch(std::string path_)
: uid(MDS_AUTH_UID_ANY), path(path_) {
normalize_path();
}
MDSCapMatch(std::string path_, int64_t uid_, std::vector<gid_t>& gids_)
: uid(uid_), gids(gids_), path(path_) {
normalize_path();
}
void normalize_path();
bool is_match_all() const
{
return uid == MDS_AUTH_UID_ANY && path == "";
}
// check whether this grant matches against a given file and caller uid:gid
bool match(const std::string &target_path,
const int caller_uid,
const int caller_gid) const;
};
struct MDSCapGrant {
MDSCapSpec spec;
MDSCapMatch match;
MDSCapGrant(const MDSCapSpec &spec_, const MDSCapMatch &match_)
: spec(spec_), match(match_) {}
MDSCapGrant() {}
};
class MDSAuthCaps
{
CephContext *cct;
std::vector<MDSCapGrant> grants;
public:
MDSAuthCaps(CephContext *cct_=NULL)
: cct(cct_) { }
// this ctor is used by spirit/phoenix; doesn't need cct.
MDSAuthCaps(const std::vector<MDSCapGrant> &grants_)
: cct(NULL), grants(grants_) { }
void set_allow_all();
bool parse(CephContext *cct, const std::string &str, std::ostream *err);
bool allow_all() const;
bool is_capable(const std::string &inode_path,
uid_t inode_uid, gid_t inode_gid, unsigned inode_mode,
uid_t uid, gid_t gid, unsigned mask,
uid_t new_uid, gid_t new_gid) const;
friend std::ostream &operator<<(std::ostream &out, const MDSAuthCaps &cap);
};
std::ostream &operator<<(std::ostream &out, const MDSCapMatch &match);
std::ostream &operator<<(std::ostream &out, const MDSCapSpec &spec);
std::ostream &operator<<(std::ostream &out, const MDSCapGrant &grant);
std::ostream &operator<<(std::ostream &out, const MDSAuthCaps &cap);
#endif // MDS_AUTH_CAPS_H