]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/mds/TestMDSAuthCaps.cc
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / test / mds / TestMDSAuthCaps.cc
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) 2012 Inktank
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 #include <iostream>
16
17 #include "include/stringify.h"
18 #include "mds/MDSAuthCaps.h"
19
20 #include "gtest/gtest.h"
21
22 using std::string;
23 using std::cout;
24
25 entity_addr_t addr;
26
27 const char *parse_good[] = {
28 "allow rw uid=1 gids=1",
29 "allow * path=\"/foo\"",
30 "allow * path=/foo",
31 "allow * path=/foo-bar_baz",
32 "allow * path=\"/foo bar/baz\"",
33 "allow * uid=1",
34 "allow * path=\"/foo\" uid=1",
35 "allow *",
36 "allow r",
37 "allow rw",
38 "allow rw uid=1 gids=1,2,3",
39 "allow rw path=/foo uid=1 gids=1,2,3",
40 "allow r, allow rw path=/foo",
41 "allow r, allow * uid=1",
42 "allow r ,allow * uid=1",
43 "allow r ;allow * uid=1",
44 "allow r ; allow * uid=1",
45 "allow r ; allow * uid=1",
46 "allow r uid=1 gids=1,2,3, allow * uid=2",
47 "allow r network 1.2.3.4/8",
48 "allow rw path=/foo uid=1 gids=1,2,3 network 2.3.4.5/16",
49 0
50 };
51
52 TEST(MDSAuthCaps, ParseGood) {
53 for (int i=0; parse_good[i]; i++) {
54 string str = parse_good[i];
55 MDSAuthCaps cap;
56 std::cout << "Testing good input: '" << str << "'" << std::endl;
57 ASSERT_TRUE(cap.parse(g_ceph_context, str, &cout));
58 }
59 }
60
61 const char *parse_bad[] = {
62 "allow r poolfoo",
63 "allow r w",
64 "ALLOW r",
65 "allow w",
66 "allow rwx,",
67 "allow rwx x",
68 "allow r pool foo r",
69 "allow wwx pool taco",
70 "allow wwx pool taco^funny&chars",
71 "allow rwx pool 'weird name''",
72 "allow rwx object_prefix \"beforepool\" pool weird",
73 "allow rwx auid 123 pool asdf",
74 "allow xrwx pool foo,, allow r pool bar",
75 ";allow rwx pool foo rwx ; allow r pool bar",
76 "allow rwx pool foo ;allow r pool bar gibberish",
77 "allow rwx auid 123 pool asdf namespace=foo",
78 "allow rwx auid 123 namespace",
79 "allow rwx namespace",
80 "allow namespace",
81 "allow namespace=foo",
82 "allow rwx auid 123 namespace asdf",
83 "allow wwx pool ''",
84 "allow rw gids=1",
85 "allow rw gids=1,2,3",
86 "allow rw uid=123 gids=asdf",
87 "allow rw uid=123 gids=1,2,asdf",
88 0
89 };
90
91 TEST(MDSAuthCaps, ParseBad) {
92 for (int i=0; parse_bad[i]; i++) {
93 string str = parse_bad[i];
94 MDSAuthCaps cap;
95 std::cout << "Testing bad input: '" << str << "'" << std::endl;
96 ASSERT_FALSE(cap.parse(g_ceph_context, str, &cout));
97 }
98 }
99
100 TEST(MDSAuthCaps, AllowAll) {
101 MDSAuthCaps cap;
102 ASSERT_FALSE(cap.allow_all());
103
104 ASSERT_TRUE(cap.parse(g_ceph_context, "allow r", NULL));
105 ASSERT_FALSE(cap.allow_all());
106 cap = MDSAuthCaps();
107
108 ASSERT_TRUE(cap.parse(g_ceph_context, "allow rw", NULL));
109 ASSERT_FALSE(cap.allow_all());
110 cap = MDSAuthCaps();
111
112 ASSERT_TRUE(cap.parse(g_ceph_context, "allow", NULL));
113 ASSERT_FALSE(cap.allow_all());
114 cap = MDSAuthCaps();
115
116 ASSERT_TRUE(cap.parse(g_ceph_context, "allow *", NULL));
117 ASSERT_TRUE(cap.allow_all());
118 ASSERT_TRUE(cap.is_capable("foo/bar", 0, 0, 0777, 0, 0, NULL, MAY_READ | MAY_WRITE, 0, 0, addr));
119 }
120
121 TEST(MDSAuthCaps, AllowUid) {
122 MDSAuthCaps cap(g_ceph_context);
123 ASSERT_TRUE(cap.parse(g_ceph_context, "allow * uid=10", NULL));
124 ASSERT_FALSE(cap.allow_all());
125
126 // uid/gid must be valid
127 ASSERT_FALSE(cap.is_capable("foo", 0, 0, 0777, 0, 0, NULL, MAY_READ, 0, 0, addr));
128 ASSERT_TRUE(cap.is_capable("foo", 0, 0, 0777, 10, 0, NULL, MAY_READ, 0, 0, addr));
129 ASSERT_TRUE(cap.is_capable("foo", 0, 0, 0777, 10, 10, NULL, MAY_READ, 0, 0, addr));
130 ASSERT_FALSE(cap.is_capable("foo", 0, 0, 0777, 12, 12, NULL, MAY_READ, 0, 0, addr));
131 ASSERT_TRUE(cap.is_capable("foo", 0, 0, 0777, 10, 13, NULL, MAY_READ, 0, 0, addr));
132 }
133
134 TEST(MDSAuthCaps, AllowUidGid) {
135 MDSAuthCaps cap(g_ceph_context);
136 ASSERT_TRUE(cap.parse(g_ceph_context, "allow * uid=10 gids=10,11,12; allow * uid=12 gids=12,10", NULL));
137 ASSERT_FALSE(cap.allow_all());
138
139 // uid/gid must be valid
140 ASSERT_FALSE(cap.is_capable("foo", 0, 0, 0777, 0, 0, NULL, MAY_READ, 0, 0, addr));
141 ASSERT_FALSE(cap.is_capable("foo", 0, 0, 0777, 10, 0, NULL, MAY_READ, 0, 0, addr));
142 ASSERT_FALSE(cap.is_capable("foo", 0, 0, 0777, 9, 10, NULL, MAY_READ, 0, 0, addr));
143 ASSERT_TRUE(cap.is_capable("foo", 0, 0, 0777, 10, 10, NULL, MAY_READ, 0, 0, addr));
144 ASSERT_TRUE(cap.is_capable("foo", 0, 0, 0777, 12, 12, NULL, MAY_READ, 0, 0, addr));
145 ASSERT_FALSE(cap.is_capable("foo", 0, 0, 0777, 10, 13, NULL, MAY_READ, 0, 0, addr));
146
147 // user
148 ASSERT_TRUE(cap.is_capable("foo", 10, 10, 0500, 10, 11, NULL, MAY_READ, 0, 0, addr));
149 ASSERT_FALSE(cap.is_capable("foo", 10, 10, 0500, 10, 11, NULL, MAY_WRITE, 0, 0, addr));
150 ASSERT_FALSE(cap.is_capable("foo", 10, 10, 0500, 10, 11, NULL, MAY_READ | MAY_WRITE, 0, 0, addr));
151 ASSERT_TRUE(cap.is_capable("foo", 10, 10, 0700, 10, 11, NULL, MAY_READ, 0, 0, addr));
152 ASSERT_TRUE(cap.is_capable("foo", 10, 10, 0700, 10, 11, NULL, MAY_WRITE, 0, 0, addr));
153 ASSERT_TRUE(cap.is_capable("foo", 10, 10, 0700, 10, 10, NULL, MAY_READ | MAY_WRITE, 0, 0, addr));
154 ASSERT_TRUE(cap.is_capable("foo", 10, 0, 0700, 10, 10, NULL, MAY_READ | MAY_WRITE, 0, 0, addr));
155 ASSERT_FALSE(cap.is_capable("foo", 12, 0, 0700, 10, 10, NULL, MAY_READ | MAY_WRITE, 0, 0, addr));
156 ASSERT_TRUE(cap.is_capable("foo", 12, 0, 0700, 12, 12, NULL, MAY_READ | MAY_WRITE, 0, 0, addr));
157 ASSERT_FALSE(cap.is_capable("foo", 0, 0, 0700, 10, 10, NULL, MAY_READ | MAY_WRITE, 0, 0, addr));
158
159 // group
160 vector<uint64_t> glist10;
161 glist10.push_back(10);
162 vector<uint64_t> dglist10;
163 dglist10.push_back(8);
164 dglist10.push_back(10);
165 vector<uint64_t> glist11;
166 glist11.push_back(11);
167 vector<uint64_t> glist12;
168 glist12.push_back(12);
169 ASSERT_TRUE(cap.is_capable("foo", 0, 10, 0750, 10, 10, NULL, MAY_READ, 0, 0, addr));
170 ASSERT_FALSE(cap.is_capable("foo", 0, 10, 0750, 10, 10, NULL, MAY_WRITE, 0, 0, addr));
171 ASSERT_TRUE(cap.is_capable("foo", 0, 10, 0770, 10, 10, NULL, MAY_READ | MAY_WRITE, 0, 0, addr));
172 ASSERT_TRUE(cap.is_capable("foo", 0, 10, 0770, 10, 11, &glist10, MAY_READ | MAY_WRITE, 0, 0, addr));
173 ASSERT_TRUE(cap.is_capable("foo", 0, 11, 0770, 10, 10, &glist11, MAY_READ | MAY_WRITE, 0, 0, addr));
174 ASSERT_TRUE(cap.is_capable("foo", 0, 11, 0770, 10, 11, NULL, MAY_READ | MAY_WRITE, 0, 0, addr));
175 ASSERT_TRUE(cap.is_capable("foo", 0, 12, 0770, 12, 12, NULL, MAY_READ | MAY_WRITE, 0, 0, addr));
176 ASSERT_FALSE(cap.is_capable("foo", 0, 10, 0770, 12, 12, NULL, MAY_READ | MAY_WRITE, 0, 0, addr));
177 ASSERT_TRUE(cap.is_capable("foo", 0, 10, 0770, 12, 12, &glist10, MAY_READ | MAY_WRITE, 0, 0, addr));
178 ASSERT_TRUE(cap.is_capable("foo", 0, 10, 0770, 12, 12, &dglist10, MAY_READ | MAY_WRITE, 0, 0, addr));
179 ASSERT_FALSE(cap.is_capable("foo", 0, 11, 0770, 12, 12, &glist11, MAY_READ | MAY_WRITE, 0, 0, addr));
180 ASSERT_FALSE(cap.is_capable("foo", 0, 12, 0770, 10, 10, NULL, MAY_READ | MAY_WRITE, 0, 0, addr));
181 ASSERT_TRUE(cap.is_capable("foo", 0, 12, 0770, 10, 10, &glist12, MAY_READ | MAY_WRITE, 0, 0, addr));
182
183 // user > group
184 ASSERT_TRUE(cap.is_capable("foo", 10, 10, 0570, 10, 10, NULL, MAY_READ, 0, 0, addr));
185 ASSERT_FALSE(cap.is_capable("foo", 10, 10, 0570, 10, 10, NULL, MAY_WRITE, 0, 0, addr));
186
187 // other
188 ASSERT_TRUE(cap.is_capable("foo", 0, 0, 0775, 10, 10, NULL, MAY_READ, 0, 0, addr));
189 ASSERT_FALSE(cap.is_capable("foo", 0, 0, 0770, 10, 10, NULL, MAY_READ, 0, 0, addr));
190 ASSERT_FALSE(cap.is_capable("foo", 0, 0, 0775, 10, 10, NULL, MAY_WRITE, 0, 0, addr));
191 ASSERT_FALSE(cap.is_capable("foo", 0, 0, 0775, 10, 10, NULL, MAY_READ | MAY_WRITE, 0, 0, addr));
192 ASSERT_TRUE(cap.is_capable("foo", 0, 0, 0777, 10, 10, NULL, MAY_READ | MAY_WRITE, 0, 0, addr));
193 ASSERT_FALSE(cap.is_capable("foo", 0, 0, 0773, 10, 10, NULL, MAY_READ, 0, 0, addr));
194
195 // group > other
196 ASSERT_TRUE(cap.is_capable("foo", 0, 0, 0557, 10, 10, NULL, MAY_READ, 0, 0, addr));
197 ASSERT_FALSE(cap.is_capable("foo", 0, 10, 0557, 10, 10, NULL, MAY_WRITE, 0, 0, addr));
198
199 // user > other
200 ASSERT_TRUE(cap.is_capable("foo", 0, 0, 0557, 10, 10, NULL, MAY_READ, 0, 0, addr));
201 ASSERT_FALSE(cap.is_capable("foo", 10, 0, 0557, 10, 10, NULL, MAY_WRITE, 0, 0, addr));
202 }
203
204 TEST(MDSAuthCaps, AllowPath) {
205 MDSAuthCaps cap;
206 ASSERT_TRUE(cap.parse(g_ceph_context, "allow * path=/sandbox", NULL));
207 ASSERT_FALSE(cap.allow_all());
208 ASSERT_TRUE(cap.is_capable("sandbox/foo", 0, 0, 0777, 0, 0, NULL, MAY_READ | MAY_WRITE, 0, 0, addr));
209 ASSERT_TRUE(cap.is_capable("sandbox", 0, 0, 0777, 0, 0, NULL, MAY_READ | MAY_WRITE, 0, 0, addr));
210 ASSERT_FALSE(cap.is_capable("sandboxed", 0, 0, 0777, 0, 0, NULL, MAY_READ | MAY_WRITE, 0, 0, addr));
211 ASSERT_FALSE(cap.is_capable("foo", 0, 0, 0777, 0, 0, NULL, MAY_READ | MAY_WRITE, 0, 0, addr));
212 }
213
214 TEST(MDSAuthCaps, AllowPathChars) {
215 MDSAuthCaps unquo_cap;
216 ASSERT_TRUE(unquo_cap.parse(g_ceph_context, "allow * path=/sandbox-._foo", NULL));
217 ASSERT_FALSE(unquo_cap.allow_all());
218 ASSERT_TRUE(unquo_cap.is_capable("sandbox-._foo/foo", 0, 0, 0777, 0, 0, NULL, MAY_READ | MAY_WRITE, 0, 0, addr));
219 ASSERT_FALSE(unquo_cap.is_capable("sandbox", 0, 0, 0777, 0, 0, NULL, MAY_READ | MAY_WRITE, 0, 0, addr));
220 ASSERT_FALSE(unquo_cap.is_capable("sandbox-._food", 0, 0, 0777, 0, 0, NULL, MAY_READ | MAY_WRITE, 0, 0, addr));
221 ASSERT_FALSE(unquo_cap.is_capable("foo", 0, 0, 0777, 0, 0, NULL, MAY_READ | MAY_WRITE, 0, 0, addr));
222 }
223
224
225 TEST(MDSAuthCaps, AllowPathCharsQuoted) {
226 MDSAuthCaps quo_cap;
227 ASSERT_TRUE(quo_cap.parse(g_ceph_context, "allow * path=\"/sandbox-._foo\"", NULL));
228 ASSERT_FALSE(quo_cap.allow_all());
229 ASSERT_TRUE(quo_cap.is_capable("sandbox-._foo/foo", 0, 0, 0777, 0, 0, NULL, MAY_READ | MAY_WRITE, 0, 0, addr));
230 ASSERT_FALSE(quo_cap.is_capable("sandbox", 0, 0, 0777, 0, 0, NULL, MAY_READ | MAY_WRITE, 0, 0, addr));
231 ASSERT_FALSE(quo_cap.is_capable("sandbox-._food", 0, 0, 0777, 0, 0, NULL, MAY_READ | MAY_WRITE, 0, 0, addr));
232 ASSERT_FALSE(quo_cap.is_capable("foo", 0, 0, 0777, 0, 0, NULL, MAY_READ | MAY_WRITE, 0, 0, addr));
233 }
234
235 TEST(MDSAuthCaps, OutputParsed) {
236 struct CapsTest {
237 const char *input;
238 const char *output;
239 };
240 CapsTest test_values[] = {
241 {"allow",
242 "MDSAuthCaps[allow rwps]"},
243 {"allow *",
244 "MDSAuthCaps[allow *]"},
245 {"allow r",
246 "MDSAuthCaps[allow r]"},
247 {"allow rw",
248 "MDSAuthCaps[allow rw]"},
249 {"allow * uid=1",
250 "MDSAuthCaps[allow * uid=1]"},
251 {"allow * uid=1 gids=1",
252 "MDSAuthCaps[allow * uid=1 gids=1]"},
253 {"allow * uid=1 gids=1,2,3",
254 "MDSAuthCaps[allow * uid=1 gids=1,2,3]"},
255 {"allow * path=/foo",
256 "MDSAuthCaps[allow * path=\"/foo\"]"},
257 {"allow * path=\"/foo\"",
258 "MDSAuthCaps[allow * path=\"/foo\"]"},
259 {"allow * path=\"/foo\" uid=1",
260 "MDSAuthCaps[allow * path=\"/foo\" uid=1]"},
261 {"allow * path=\"/foo\" uid=1 gids=1,2,3",
262 "MDSAuthCaps[allow * path=\"/foo\" uid=1 gids=1,2,3]"},
263 {"allow r uid=1 gids=1,2,3, allow * uid=2",
264 "MDSAuthCaps[allow r uid=1 gids=1,2,3, allow * uid=2]"},
265 {"allow r uid=1 gids=1,2,3, allow * uid=2 network 10.0.0.0/8",
266 "MDSAuthCaps[allow r uid=1 gids=1,2,3, allow * uid=2 network 10.0.0.0/8]"},
267 };
268 size_t num_tests = sizeof(test_values) / sizeof(*test_values);
269 for (size_t i = 0; i < num_tests; ++i) {
270 MDSAuthCaps cap;
271 std::cout << "Testing input '" << test_values[i].input << "'" << std::endl;
272 ASSERT_TRUE(cap.parse(g_ceph_context, test_values[i].input, &cout));
273 ASSERT_EQ(test_values[i].output, stringify(cap));
274 }
275 }
276
277 TEST(MDSAuthCaps, network) {
278 entity_addr_t a, b, c;
279 a.parse("10.1.2.3");
280 b.parse("192.168.2.3");
281 c.parse("192.167.2.3");
282
283 MDSAuthCaps cap;
284 ASSERT_TRUE(cap.parse(g_ceph_context, "allow * network 192.168.0.0/16, allow * network 10.0.0.0/8", NULL));
285
286 ASSERT_TRUE(cap.is_capable("foo", 0, 0, 0777, 0, 0, NULL, MAY_READ, 0, 0, a));
287 ASSERT_TRUE(cap.is_capable("foo", 0, 0, 0777, 0, 0, NULL, MAY_READ, 0, 0, b));
288 ASSERT_FALSE(cap.is_capable("foo", 0, 0, 0777, 0, 0, NULL, MAY_READ, 0, 0, c));
289 }