]>
git.proxmox.com Git - ceph.git/blob - 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
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2012 Inktank
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.
17 #include "include/stringify.h"
18 #include "mds/MDSAuthCaps.h"
20 #include "gtest/gtest.h"
27 const char *parse_good
[] = {
28 "allow rw uid=1 gids=1",
29 "allow * path=\"/foo\"",
31 "allow * path=/foo-bar_baz",
32 "allow * path=\"/foo bar/baz\"",
34 "allow * path=\"/foo\" uid=1",
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",
52 TEST(MDSAuthCaps
, ParseGood
) {
53 for (int i
=0; parse_good
[i
]; i
++) {
54 string str
= parse_good
[i
];
56 std::cout
<< "Testing good input: '" << str
<< "'" << std::endl
;
57 ASSERT_TRUE(cap
.parse(g_ceph_context
, str
, &cout
));
61 const char *parse_bad
[] = {
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",
81 "allow namespace=foo",
82 "allow rwx auid 123 namespace asdf",
85 "allow rw gids=1,2,3",
86 "allow rw uid=123 gids=asdf",
87 "allow rw uid=123 gids=1,2,asdf",
91 TEST(MDSAuthCaps
, ParseBad
) {
92 for (int i
=0; parse_bad
[i
]; i
++) {
93 string str
= parse_bad
[i
];
95 std::cout
<< "Testing bad input: '" << str
<< "'" << std::endl
;
96 ASSERT_FALSE(cap
.parse(g_ceph_context
, str
, &cout
));
100 TEST(MDSAuthCaps
, AllowAll
) {
102 ASSERT_FALSE(cap
.allow_all());
104 ASSERT_TRUE(cap
.parse(g_ceph_context
, "allow r", NULL
));
105 ASSERT_FALSE(cap
.allow_all());
108 ASSERT_TRUE(cap
.parse(g_ceph_context
, "allow rw", NULL
));
109 ASSERT_FALSE(cap
.allow_all());
112 ASSERT_TRUE(cap
.parse(g_ceph_context
, "allow", NULL
));
113 ASSERT_FALSE(cap
.allow_all());
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
));
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());
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
));
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());
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
));
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
));
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
));
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
));
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
));
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
));
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
));
204 TEST(MDSAuthCaps
, AllowPath
) {
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
));
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
));
225 TEST(MDSAuthCaps
, AllowPathCharsQuoted
) {
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
));
235 TEST(MDSAuthCaps
, OutputParsed
) {
240 CapsTest test_values
[] = {
242 "MDSAuthCaps[allow rwps]"},
244 "MDSAuthCaps[allow *]"},
246 "MDSAuthCaps[allow r]"},
248 "MDSAuthCaps[allow rw]"},
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]"},
268 size_t num_tests
= sizeof(test_values
) / sizeof(*test_values
);
269 for (size_t i
= 0; i
< num_tests
; ++i
) {
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
));
277 TEST(MDSAuthCaps
, network
) {
278 entity_addr_t a
, b
, c
;
280 b
.parse("192.168.2.3");
281 c
.parse("192.167.2.3");
284 ASSERT_TRUE(cap
.parse(g_ceph_context
, "allow * network 192.168.0.0/16, allow * network 10.0.0.0/8", NULL
));
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
));