initial code repo
[stor4nfv.git] / src / ceph / src / test / osd / osdcap.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 "osd/OSDCap.h"
19
20 #include "gtest/gtest.h"
21
22 const char *parse_good[] = {
23   "allow *",
24   "allow r",
25   "allow rwx",
26   "allow r pool foo ",
27   "allow r pool=foo",
28   "allow wx pool taco",
29   "allow pool foo r",
30   "allow pool taco wx",
31   "allow wx pool taco object_prefix obj",
32   "allow wx pool taco object_prefix obj_with_underscores_and_no_quotes",
33   "allow pool taco object_prefix obj wx",
34   "allow pool taco object_prefix obj_with_underscores_and_no_quotes wx",
35   "allow rwx pool 'weird name'",
36   "allow rwx pool \"weird name with ''s\"",
37   "allow rwx auid 123",
38   "allow rwx pool foo, allow r pool bar",
39   "allow rwx pool foo ; allow r pool bar",
40   "allow rwx pool foo ;allow r pool bar",
41   "allow rwx pool foo; allow r pool bar",
42   "allow auid 123 rwx",
43   "allow pool foo rwx, allow pool bar r",
44   "allow pool foo.froo.foo rwx, allow pool bar r",
45   "allow pool foo rwx ; allow pool bar r",
46   "allow pool foo rwx ;allow pool bar r",
47   "allow pool foo rwx; allow pool bar r",
48   "allow pool data rw, allow pool rbd rwx, allow pool images class rbd foo",
49   "allow class-read",
50   "allow class-write",
51   "allow class-read class-write",
52   "allow r class-read pool foo",
53   "allow rw class-read class-write pool foo",
54   "allow r class-read pool foo",
55   "allow pool bar rwx; allow pool baz r class-read",
56   "allow class foo",
57   "allow class clsname \"clsthingidon'tunderstand\"",
58   "  allow rwx pool foo; allow r pool bar  ",
59   "  allow   rwx   pool foo; allow r pool bar  ",
60   "  allow pool foo rwx; allow pool bar r  ",
61   "  allow     pool foo rwx; allow pool bar r  ",
62   " allow wx pool taco",
63   "\tallow\nwx\tpool \n taco\t",
64   "allow r   pool    foo    object_prefix   blah   ;   allow   w   auid  5",
65   "allow class-read object_prefix rbd_children, allow pool libvirt-pool-test rwx",
66   "allow class-read object_prefix rbd-children, allow pool libvirt_pool_test rwx",
67   "allow pool foo namespace nfoo rwx, allow pool bar namespace=nbar r",
68   "allow pool foo namespace=nfoo rwx ; allow pool bar namespace=nbar r",
69   "allow pool foo namespace nfoo rwx ;allow pool bar namespace nbar r",
70   "allow pool foo namespace=nfoo rwx; allow pool bar namespace nbar object_prefix rbd r",
71   "allow pool foo namespace=\"\" rwx; allow pool bar namespace='' object_prefix rbd r",
72   "allow pool foo namespace \"\" rwx; allow pool bar namespace '' object_prefix rbd r",
73   "profile abc, profile abc pool=bar, profile abc pool=bar namespace=foo",
74   0
75 };
76
77 TEST(OSDCap, ParseGood) {
78   for (int i=0; parse_good[i]; i++) {
79     string str = parse_good[i];
80     OSDCap cap;
81     std::cout << "Testing good input: '" << str << "'" << std::endl;
82     ASSERT_TRUE(cap.parse(str, &cout));
83   }
84 }
85
86 const char *parse_bad[] = {
87   "allow r poolfoo",
88   "allow r w",
89   "ALLOW r",
90   "allow rwx,",
91   "allow rwx x",
92   "allow r pool foo r",
93   "allow wwx pool taco",
94   "allow wwx pool taco^funny&chars",
95   "allow rwx pool 'weird name''",
96   "allow rwx object_prefix \"beforepool\" pool weird",
97   "allow rwx auid 123 pool asdf",
98   "allow xrwx pool foo,, allow r pool bar",
99   ";allow rwx pool foo rwx ; allow r pool bar",
100   "allow rwx pool foo ;allow r pool bar gibberish",
101   "allow rwx auid 123 pool asdf namespace=foo",
102   "allow rwx auid 123 namespace",
103   "allow rwx namespace",
104   "allow namespace",
105   "allow namespace=foo",
106   "allow rwx auid 123 namespace asdf",
107   "allow wwx pool ''",
108   0
109 };
110
111 TEST(OSDCap, ParseBad) {
112   for (int i=0; parse_bad[i]; i++) {
113     string str = parse_bad[i];
114     OSDCap cap;
115     std::cout << "Testing bad input: '" << str << "'" << std::endl;
116     ASSERT_FALSE(cap.parse(str, &cout));
117   }
118 }
119
120 TEST(OSDCap, AllowAll) {
121   OSDCap cap;
122   ASSERT_FALSE(cap.allow_all());
123
124   ASSERT_TRUE(cap.parse("allow r", NULL));
125   ASSERT_FALSE(cap.allow_all());
126   cap.grants.clear();
127
128   ASSERT_TRUE(cap.parse("allow w", NULL));
129   ASSERT_FALSE(cap.allow_all());
130   cap.grants.clear();
131
132   ASSERT_TRUE(cap.parse("allow x", NULL));
133   ASSERT_FALSE(cap.allow_all());
134   cap.grants.clear();
135
136   ASSERT_TRUE(cap.parse("allow rwx", NULL));
137   ASSERT_FALSE(cap.allow_all());
138   cap.grants.clear();
139
140   ASSERT_TRUE(cap.parse("allow rw", NULL));
141   ASSERT_FALSE(cap.allow_all());
142   cap.grants.clear();
143
144   ASSERT_TRUE(cap.parse("allow rx", NULL));
145   ASSERT_FALSE(cap.allow_all());
146   cap.grants.clear();
147
148   ASSERT_TRUE(cap.parse("allow wx", NULL));
149   ASSERT_FALSE(cap.allow_all());
150   cap.grants.clear();
151
152   ASSERT_TRUE(cap.parse("allow *", NULL));
153   ASSERT_TRUE(cap.allow_all());
154   ASSERT_TRUE(cap.is_capable("foo", "", 0, "asdf", true, true, {{"cls", true, true, true}}));
155   ASSERT_TRUE(cap.is_capable("foo", "anamespace", 0, "asdf", true, true, {{"cls", true, true, true}}));
156   ASSERT_TRUE(cap.is_capable("bar", "", 0, "asdf", true, true, {{"cls", true, true, true}}));
157   ASSERT_TRUE(cap.is_capable("bar", "anamespace", 0, "asdf", true, true, {{"cls", true, true, true}}));
158
159   // 'allow *' overrides whitelist
160   ASSERT_TRUE(cap.is_capable("foo", "", 0, "asdf", true, true, {{"cls", true, true, false}}));
161   ASSERT_TRUE(cap.is_capable("foo", "anamespace", 0, "asdf", true, true, {{"cls", true, true, false}}));
162   ASSERT_TRUE(cap.is_capable("bar", "", 0, "asdf", true, true, {{"cls", true, true, false}}));
163   ASSERT_TRUE(cap.is_capable("bar", "anamespace", 0, "asdf", true, true, {{"cls", true, true, false}}));
164 }
165
166 TEST(OSDCap, AllowPool) {
167   OSDCap cap;
168   bool r = cap.parse("allow rwx pool foo", NULL);
169   ASSERT_TRUE(r);
170
171   ASSERT_TRUE(cap.is_capable("foo", "", 0, "", true, true, {{"cls", true, true, true}}));
172   ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "", true, true, {{"cls", true, true, true}}));
173   // true->false for classes not on whitelist
174   ASSERT_FALSE(cap.is_capable("foo", "", 0, "", true, true, {{"cls", true, true, false}}));
175   ASSERT_FALSE(cap.is_capable("foo", "ns", 0, "", true, true, {{"cls", true, true, false}}));
176
177   ASSERT_FALSE(cap.is_capable("bar", "", 0, "", true, true, {{"cls", true, true, true}}));
178   ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "", true, true, {{"cls", true, true, true}}));
179 }
180
181 TEST(OSDCap, AllowPools) {
182   OSDCap cap;
183   bool r = cap.parse("allow rwx pool foo, allow r pool bar", NULL);
184   ASSERT_TRUE(r);
185
186   ASSERT_TRUE(cap.is_capable("foo", "", 0, "", true, true, {{"cls", true, true, true}}));
187   ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "", true, true, {{"cls", true, true, true}}));
188   // true-false for classes not on whitelist
189   ASSERT_FALSE(cap.is_capable("foo", "", 0, "", true, true, {{"cls", true, true, false}}));
190   ASSERT_FALSE(cap.is_capable("foo", "ns", 0, "", true, true, {{"cls", true, true, false}}));
191
192   ASSERT_TRUE(cap.is_capable("bar", "", 0, "", true, false, {}));
193   ASSERT_TRUE(cap.is_capable("bar", "ns", 0, "", true, false, {}));
194
195   ASSERT_FALSE(cap.is_capable("bar", "", 0, "", true, true, {{"cls", true, true, true}}));
196   ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "", true, true, {{"cls", true, true, true}}));
197
198   ASSERT_FALSE(cap.is_capable("baz", "", 0, "", true, false, {}));
199   ASSERT_FALSE(cap.is_capable("baz", "ns", 0, "", true, false, {}));
200 }
201
202 TEST(OSDCap, AllowPools2) {
203   OSDCap cap;
204   bool r = cap.parse("allow r, allow rwx pool foo", NULL);
205   ASSERT_TRUE(r);
206
207   ASSERT_TRUE(cap.is_capable("foo", "", 0, "", true, true, {{"cls", true, true, true}}));
208   // true-false for classes not on whitelist
209   ASSERT_FALSE(cap.is_capable("foo", "", 0, "", true, true, {{"cls", true, true, false}}));
210   ASSERT_FALSE(cap.is_capable("bar", "", 0, "", true, true, {{"cls", true, true, true}}));
211
212   ASSERT_TRUE(cap.is_capable("bar", "", 0, "", true, false, {}));
213 }
214
215 TEST(OSDCap, ObjectPrefix) {
216   OSDCap cap;
217   bool r = cap.parse("allow rwx object_prefix foo", NULL);
218   ASSERT_TRUE(r);
219
220   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, true}}));
221   ASSERT_TRUE(cap.is_capable("bar", "", 0, "food", true, true, {{"cls", true, true, true}}));
222   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo_bar", true, true, {{"cls", true, true, true}}));
223   // true-false for classes not on whitelist
224   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, false}}));
225   ASSERT_FALSE(cap.is_capable("bar", "", 0, "food", true, true, {{"cls", true, true, false}}));
226   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo_bar", true, true, {{"cls", true, true, false}}));
227
228   ASSERT_FALSE(cap.is_capable("bar", "", 0, "_foo", true, true, {{"cls", true, true, true}}));
229   ASSERT_FALSE(cap.is_capable("bar", "", 0, " foo ", true, true, {{"cls", true, true, true}}));
230   ASSERT_FALSE(cap.is_capable("bar", "", 0, "fo", true, true, {{"cls", true, true, true}}));
231 }
232
233 TEST(OSDCap, ObjectPoolAndPrefix) {
234   OSDCap cap;
235   bool r = cap.parse("allow rwx pool bar object_prefix foo", NULL);
236   ASSERT_TRUE(r);
237
238   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, true}}));
239   ASSERT_TRUE(cap.is_capable("bar", "", 0, "food", true, true, {{"cls", true, true, true}}));
240   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo_bar", true, true, {{"cls", true, true, true}}));
241   // true-false for classes not on whitelist
242   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, false}}));
243   ASSERT_FALSE(cap.is_capable("bar", "", 0, "food", true, true, {{"cls", true, true, false}}));
244   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo_bar", true, true, {{"cls", true, true, false}}));
245
246   ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, true, {{"cls", true, true, true}}));
247   ASSERT_FALSE(cap.is_capable("baz", "", 0, "food", true, true, {{"cls", true, true, true}}));
248   ASSERT_FALSE(cap.is_capable("baz", "", 0, "fo", true, true, {{"cls", true, true, true}}));
249 }
250
251 TEST(OSDCap, BasicR) {
252   OSDCap cap;
253   ASSERT_TRUE(cap.parse("allow r", NULL));
254
255   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, {}));
256
257   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {{"cls", false, true, true}}));
258   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", true, false, true}}));
259   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, true}}));
260   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {{"cls", false, true, true}}));
261   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {}));
262 }
263
264 TEST(OSDCap, BasicW) {
265   OSDCap cap;
266   ASSERT_TRUE(cap.parse("allow w", NULL));
267
268   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, {}));
269
270   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {{"cls", false, true, true}}));
271   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", true, false, true}}));
272   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, true}}));
273   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, {}));
274   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {}));
275 }
276
277 TEST(OSDCap, BasicX) {
278   OSDCap cap;
279   ASSERT_TRUE(cap.parse("allow x", NULL));
280
281   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", false, true, true}}));
282   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, false, true}}));
283   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, true, true}}));
284   // true->false when class not on whitelist
285   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", false, true, false}}));
286   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, false, false}}));
287   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, true, false}}));
288
289   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {}));
290   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, {}));
291   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {}));
292 }
293
294 TEST(OSDCap, BasicRW) {
295   OSDCap cap;
296   ASSERT_TRUE(cap.parse("allow rw", NULL));
297
298   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, {}));
299   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, {}));
300   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, {}));
301
302   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {{"cls", false, true, true}}));
303   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", true, false, true}}));
304   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, true}}));
305 }
306
307 TEST(OSDCap, BasicRX) {
308   OSDCap cap;
309   ASSERT_TRUE(cap.parse("allow rx", NULL));
310
311   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", true, false, true}}));
312   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, {}));
313   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", false, true, true}}));
314   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", true, true, true}}));
315   // true->false for class not on whitelist
316   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", true, false, false}}));
317   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", false, true, false}}));
318   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", true, true, false}}));
319
320   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {}));
321   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {}));
322 }
323
324 TEST(OSDCap, BasicWX) {
325   OSDCap cap;
326   ASSERT_TRUE(cap.parse("allow wx", NULL));
327
328   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, {}));
329   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, {{"cls", false, true, true}}));
330   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, false, true}}));
331   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, {{"cls", true, true, true}}));
332   // true->false for class not on whitelist
333   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {{"cls", false, true, false}}));
334   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, false, false}}));
335   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {{"cls", true, true, false}}));
336
337   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, {}));
338   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {}));
339 }
340
341 TEST(OSDCap, BasicRWX) {
342   OSDCap cap;
343   ASSERT_TRUE(cap.parse("allow rwx", NULL));
344
345   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {}));
346   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, true, true}}));
347   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, true}}));
348   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, {{"cls", true, true, true}}));
349   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", false, true, true}}));
350   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, {}));
351   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", false, true, true}}));
352   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, false, true}}));
353   // true->false for class not on whitelist
354   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, true, false}}));
355   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, false}}));
356   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {{"cls", true, true, false}}));
357   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", false, true, false}}));
358   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", false, true, false}}));
359   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, false, false}}));
360 }
361
362 TEST(OSDCap, BasicRWClassRClassW) {
363   OSDCap cap;
364   ASSERT_TRUE(cap.parse("allow rw class-read class-write", NULL));
365
366   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {}));
367   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, true, true}}));
368   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, true}}));
369   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, {{"cls", true, true, true}}));
370   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", false, true, true}}));
371   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, {}));
372   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", false, true, true}}));
373   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, false, true}}));
374   // true->false when class not whitelisted
375   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, true, false}}));
376   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, false}}));
377   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {{"cls", true, true, false}}));
378   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", false, true, false}}));
379   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", false, true, false}}));
380   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, false, false}}));
381 }
382
383 TEST(OSDCap, ClassR) {
384   OSDCap cap;
385   ASSERT_TRUE(cap.parse("allow class-read", NULL));
386
387   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, false, true}}));
388   // true->false when class not whitelisted
389   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, false, false}}));
390
391   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, {}));
392   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {}));
393   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", false, true, true}}));
394   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, true}}));
395 }
396
397 TEST(OSDCap, ClassW) {
398   OSDCap cap;
399   ASSERT_TRUE(cap.parse("allow class-write", NULL));
400
401   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", false, true, true}}));
402   // true->false when class not whitelisted
403   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", false, true, false}}));
404
405   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, {}));
406   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {}));
407   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, false, true}}));
408   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, true}}));
409 }
410
411 TEST(OSDCap, ClassRW) {
412   OSDCap cap;
413   ASSERT_TRUE(cap.parse("allow class-read class-write", NULL));
414
415   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", false, true, true}}));
416   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, false, true}}));
417   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, true, true}}));
418   // true->false when class not whitelisted
419   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", false, true, false}}));
420   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, false, false}}));
421   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, true, false}}));
422
423   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, {}));
424   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {}));
425   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, false, true}}));
426   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, true}}));
427 }
428
429 TEST(OSDCap, BasicRClassR) {
430   OSDCap cap;
431   ASSERT_TRUE(cap.parse("allow r class-read", NULL));
432
433   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, false, true}}));
434   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", true, false, true}}));
435   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, {}));
436   // true->false when class not whitelisted
437   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, false, false}}));
438   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", true, false, false}}));
439
440   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {{"cls", true, true, true}}));
441   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, true}}));
442   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {}));
443   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {}));
444
445   ASSERT_TRUE(cap.is_capable("bar", "any", 0, "foo", false, false, {{"cls", true, false, true}}));
446   ASSERT_TRUE(cap.is_capable("bar", "any", 0, "foo", true, false, {{"cls", true, false, true}}));
447   ASSERT_TRUE(cap.is_capable("bar", "any", 0, "foo", true, false, {}));
448   // true->false when class not whitelisted
449   ASSERT_FALSE(cap.is_capable("bar", "any", 0, "foo", false, false, {{"cls", true, false, false}}));
450   ASSERT_FALSE(cap.is_capable("bar", "any", 0, "foo", true, false, {{"cls", true, false, false}}));
451
452   ASSERT_FALSE(cap.is_capable("bar", "any", 0, "foo", false, true, {{"cls", true, true, true}}));
453   ASSERT_FALSE(cap.is_capable("bar", "any", 0, "foo", true, true, {{"cls", true, true, true}}));
454   ASSERT_FALSE(cap.is_capable("bar", "any", 0, "foo", false, true, {}));
455   ASSERT_FALSE(cap.is_capable("bar", "any", 0, "foo", true, true, {}));
456 }
457
458 TEST(OSDCap, PoolClassR) {
459   OSDCap cap;
460   ASSERT_TRUE(cap.parse("allow pool bar r class-read, allow pool foo rwx", NULL));
461
462   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, false, true}}));
463   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", true, false, true}}));
464   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, {}));
465   // true->false when class not whitelisted
466   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, false, false}}));
467   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", true, false, false}}));
468
469   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {{"cls", true, true, true}}));
470   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, true}}));
471   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {}));
472   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {}));
473
474   ASSERT_TRUE(cap.is_capable("bar", "ns", 0, "foo", false, false, {{"cls", true, false, true}}));
475   ASSERT_TRUE(cap.is_capable("bar", "ns", 0, "foo", true, false, {{"cls", true, false, true}}));
476   ASSERT_TRUE(cap.is_capable("bar", "ns", 0, "foo", true, false, {}));
477   // true->false when class not whitelisted
478   ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", false, false, {{"cls", true, false, false}}));
479   ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", true, false, {{"cls", true, false, false}}));
480
481   ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", false, true, {{"cls", true, true, true}}));
482   ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", true, true, {{"cls", true, true, true}}));
483   ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", false, true, {}));
484   ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", true, true, {}));
485
486   ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", false, false, {}));
487   ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", false, false, {{"cls", true, true, true}}));
488   ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, true, {{"cls", true, true, true}}));
489   ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", false, true, {{"cls", true, true, true}}));
490   ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, false, {{"cls", false, true, true}}));
491   ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, false, {}));
492   ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, true, {{"cls", false, true, true}}));
493   ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, true, {{"cls", true, false, true}}));
494   // true->false when class not whitelisted
495   ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", false, false, {{"cls", true, true, false}}));
496   ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, true, {{"cls", true, true, false}}));
497   ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", false, true, {{"cls", true, true, false}}));
498   ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, false, {{"cls", false, true, false}}));
499   ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, true, {{"cls", false, true, false}}));
500   ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, true, {{"cls", true, false, false}}));
501
502   ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", false, false, {}));
503   ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", false, false, {{"cls", true, true, true}}));
504   ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, true, {{"cls", true, true, true}}));
505   ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", false, true, {{"cls", true, true, true}}));
506   ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, false, {{"cls", false, true, true}}));
507   ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, false, {}));
508   ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, true, {{"cls", false, true, true}}));
509   ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, true, {{"cls", true, false, true}}));
510   // true->false when class not whitelisted
511   ASSERT_FALSE(cap.is_capable("foo", "ns", 0, "foo", false, false, {{"cls", true, true, false}}));
512   ASSERT_FALSE(cap.is_capable("foo", "ns", 0, "foo", true, true, {{"cls", true, true, false}}));
513   ASSERT_FALSE(cap.is_capable("foo", "ns", 0, "foo", false, true, {{"cls", true, true, false}}));
514   ASSERT_FALSE(cap.is_capable("foo", "ns", 0, "foo", true, false, {{"cls", false, true, false}}));
515   ASSERT_FALSE(cap.is_capable("foo", "ns", 0, "foo", true, true, {{"cls", false, true, false}}));
516   ASSERT_FALSE(cap.is_capable("foo", "ns", 0, "foo", true, true, {{"cls", true, false, false}}));
517
518   ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", false, false, {}));
519   ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", false, false, {{"cls", true, true, true}}));
520   ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, true, {{"cls", true, true, true}}));
521   ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", false, true, {{"cls", true, true, true}}));
522   ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, false, {{"cls", false, true, true}}));
523   ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, false, {}));
524   ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, true, {{"cls", false, true, true}}));
525   ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, true, {{"cls", true, false, true}}));
526 }
527
528 TEST(OSDCap, PoolClassRNS) {
529   OSDCap cap;
530   ASSERT_TRUE(cap.parse("allow pool bar namespace='' r class-read, allow pool foo namespace=ns rwx", NULL));
531
532   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, false, true}}));
533   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", true, false, true}}));
534   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, {}));
535   // true->false when class not whitelisted
536   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, false, false}}));
537   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", true, false, false}}));
538
539   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {{"cls", true, true, true}}));
540   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, true}}));
541   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {}));
542   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {}));
543
544   ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", false, false, {{"cls", true, false, true}}));
545   ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", true, false, {{"cls", true, false, true}}));
546   ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", true, false, {}));
547
548   ASSERT_FALSE(cap.is_capable("bar", "other", 0, "foo", false, true, {{"cls", true, true, true}}));
549   ASSERT_FALSE(cap.is_capable("bar", "other", 0, "foo", true, true, {{"cls", true, true, true}}));
550   ASSERT_FALSE(cap.is_capable("bar", "other", 0, "foo", false, true, {}));
551   ASSERT_FALSE(cap.is_capable("bar", "other", 0, "foo", true, true, {}));
552
553   ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", false, false, {}));
554   ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", false, false, {{"cls", true, true, true}}));
555   ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, true, {{"cls", true, true, true}}));
556   ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", false, true, {{"cls", true, true, true}}));
557   ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, false, {{"cls", false, true, true}}));
558   ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, false, {}));
559   ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, true, {{"cls", false, true, true}}));
560   ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, true, {{"cls", true, false, true}}));
561
562   ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", false, false, {}));
563   ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", false, false, {{"cls", true, true, true}}));
564   ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, true, {{"cls", true, true, true}}));
565   ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", false, true, {{"cls", true, true, true}}));
566   ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, false, {{"cls", false, true, true}}));
567   ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, false, {}));
568   ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, true, {{"cls", false, true, true}}));
569   ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, true, {{"cls", true, false, true}}));
570   // true->false when class not whitelisted
571   ASSERT_FALSE(cap.is_capable("foo", "ns", 0, "foo", false, false, {{"cls", true, true, false}}));
572   ASSERT_FALSE(cap.is_capable("foo", "ns", 0, "foo", true, true, {{"cls", true, true, false}}));
573   ASSERT_FALSE(cap.is_capable("foo", "ns", 0, "foo", false, true, {{"cls", true, true, false}}));
574   ASSERT_FALSE(cap.is_capable("foo", "ns", 0, "foo", true, false, {{"cls", false, true, false}}));
575   ASSERT_FALSE(cap.is_capable("foo", "ns", 0, "foo", true, true, {{"cls", false, true, false}}));
576   ASSERT_FALSE(cap.is_capable("foo", "ns", 0, "foo", true, true, {{"cls", true, false, false}}));
577
578   ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", false, false, {}));
579   ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", false, false, {{"cls", true, true, true}}));
580   ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, true, {{"cls", true, true, true}}));
581   ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", false, true, {{"cls", true, true, true}}));
582   ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, false, {{"cls", false, true, true}}));
583   ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, false, {}));
584   ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, true, {{"cls", false, true, true}}));
585   ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, true, {{"cls", true, false, true}}));
586 }
587
588 TEST(OSDCap, NSClassR) {
589   OSDCap cap;
590   ASSERT_TRUE(cap.parse("allow namespace '' rw class-read class-write, allow namespace test r", NULL));
591
592   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {}));
593   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, true, true}}));
594   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, true}}));
595   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, {{"cls", true, true, true}}));
596   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", false, true, true}}));
597   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, {}));
598   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", false, true, true}}));
599   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, false, true}}));
600   // true->false when class not whitelisted
601   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"cls", true, true, false}}));
602   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, true, false}}));
603   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, {{"cls", true, true, false}}));
604   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, {{"cls", false, true, false}}));
605   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", false, true, false}}));
606   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, {{"cls", true, false, false}}));
607
608   ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", false, false, {}));
609   ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", false, false, {{"cls", true, true, true}}));
610   ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, true, {{"cls", true, true, true}}));
611   ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", false, true, {{"cls", true, true, true}}));
612   ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, false, {{"cls", false, true, true}}));
613   ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, false, {}));
614   ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, true, {{"cls", false, true, true}}));
615   ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, true, {{"cls", true, false, true}}));
616   // true->false when class not whitelisted
617   ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", false, false, {{"cls", true, true, false}}));
618   ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, true, {{"cls", true, true, false}}));
619   ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", false, true, {{"cls", true, true, false}}));
620   ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, false, {{"cls", false, true, false}}));
621   ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, true, {{"cls", false, true, false}}));
622   ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, true, {{"cls", true, false, false}}));
623
624   ASSERT_TRUE(cap.is_capable("bar", "test", 0, "foo", true, false, {}));
625
626   ASSERT_FALSE(cap.is_capable("bar", "test", 0, "foo", false, true, {{"cls", false, true, true}}));
627   ASSERT_FALSE(cap.is_capable("bar", "test", 0, "foo", true, false, {{"cls", true, false, true}}));
628   ASSERT_FALSE(cap.is_capable("bar", "test", 0, "foo", true, true, {{"cls", true, true, true}}));
629   ASSERT_FALSE(cap.is_capable("bar", "test", 0, "foo", false, true, {{"cls", false, true, true}}));
630   ASSERT_FALSE(cap.is_capable("bar", "test", 0, "foo", true, true, {}));
631
632   ASSERT_TRUE(cap.is_capable("foo", "test", 0, "foo", true, false, {}));
633
634   ASSERT_FALSE(cap.is_capable("foo", "test", 0, "foo", false, true, {{"cls", false, true, true}}));
635   ASSERT_FALSE(cap.is_capable("foo", "test", 0, "foo", true, false, {{"cls", true, false, true}}));
636   ASSERT_FALSE(cap.is_capable("foo", "test", 0, "foo", true, true, {{"cls", true, true, true}}));
637   ASSERT_FALSE(cap.is_capable("foo", "test", 0, "foo", false, true, {{"cls", false, true, true}}));
638   ASSERT_FALSE(cap.is_capable("foo", "test", 0, "foo", true, true, {}));
639
640   ASSERT_FALSE(cap.is_capable("foo", "bad", 0, "foo", true, false, {}));
641   ASSERT_FALSE(cap.is_capable("foo", "bad", 0, "foo", false, true, {}));
642   ASSERT_FALSE(cap.is_capable("foo", "bad", 0, "foo", false, false, {{"cls", true, false, true}}));
643   ASSERT_FALSE(cap.is_capable("foo", "bad", 0, "foo", false, false, {{"cls", false, true, true}}));
644 }
645
646 TEST(OSDCap, OutputParsed)
647 {
648   struct CapsTest {
649     const char *input;
650     const char *output;
651   };
652   CapsTest test_values[] = {
653     {"allow *",
654      "osdcap[grant(*)]"},
655     {"allow r",
656      "osdcap[grant(r)]"},
657     {"allow rx",
658      "osdcap[grant(rx)]"},
659     {"allow rwx",
660      "osdcap[grant(rwx)]"},
661     {"allow rw class-read class-write",
662      "osdcap[grant(rwx)]"},
663     {"allow rw class-read",
664      "osdcap[grant(rw class-read)]"},
665     {"allow rw class-write",
666      "osdcap[grant(rw class-write)]"},
667     {"allow rwx pool images",
668      "osdcap[grant(pool images rwx)]"},
669     {"allow r pool images",
670      "osdcap[grant(pool images r)]"},
671     {"allow pool images rwx",
672      "osdcap[grant(pool images rwx)]"},
673     {"allow pool images r",
674      "osdcap[grant(pool images r)]"},
675     {"allow pool images w",
676      "osdcap[grant(pool images w)]"},
677     {"allow pool images x",
678      "osdcap[grant(pool images x)]"},
679     {"allow r pool images namespace ''",
680      "osdcap[grant(pool images namespace \"\" r)]"},
681     {"allow r pool images namespace foo",
682      "osdcap[grant(pool images namespace foo r)]"},
683     {"allow r pool images namespace \"\"",
684      "osdcap[grant(pool images namespace \"\" r)]"},
685     {"allow r namespace foo",
686      "osdcap[grant(namespace foo r)]"},
687     {"allow pool images r; allow pool rbd rwx",
688      "osdcap[grant(pool images r),grant(pool rbd rwx)]"},
689     {"allow pool images r, allow pool rbd rwx",
690      "osdcap[grant(pool images r),grant(pool rbd rwx)]"},
691     {"allow class-read object_prefix rbd_children, allow pool libvirt-pool-test rwx",
692      "osdcap[grant(object_prefix rbd_children  class-read),grant(pool libvirt-pool-test rwx)]"}
693   };
694
695   size_t num_tests = sizeof(test_values) / sizeof(*test_values);
696   for (size_t i = 0; i < num_tests; ++i) {
697     OSDCap cap;
698     std::cout << "Testing input '" << test_values[i].input << "'" << std::endl;
699     ASSERT_TRUE(cap.parse(test_values[i].input));
700     ASSERT_EQ(test_values[i].output, stringify(cap));
701   }
702 }
703
704 TEST(OSDCap, AllowClass) {
705   OSDCap cap;
706   ASSERT_TRUE(cap.parse("allow class foo", NULL));
707
708   // can call any method on class foo regardless of whitelist status
709   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}}));
710   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}}));
711   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}}));
712   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}}));
713   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}}));
714   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}}));
715
716   // does not permit invoking class bar
717   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"bar", true, false, true}}));
718   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"bar", false, true, true}}));
719   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"bar", true, true, true}}));
720   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"bar", true, false, false}}));
721   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"bar", false, true, false}}));
722   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"bar", true, true, false}}));
723 }
724
725 TEST(OSDCap, AllowClass2) {
726   OSDCap cap;
727   ASSERT_TRUE(cap.parse("allow class foo, allow class bar", NULL));
728
729   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}}));
730   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}}));
731   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}}));
732   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}}));
733   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}}));
734   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}}));
735
736   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"bar", true, false, true}}));
737   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"bar", false, true, true}}));
738   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"bar", true, true, true}}));
739   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"bar", true, false, false}}));
740   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"bar", false, true, false}}));
741   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"bar", true, true, false}}));
742 }
743
744 TEST(OSDCap, AllowClassRWX) {
745   OSDCap cap;
746   ASSERT_TRUE(cap.parse("allow rwx, allow class foo", NULL));
747
748   // can call any method on class foo regardless of whitelist status
749   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}}));
750   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}}));
751   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}}));
752   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}}));
753   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}}));
754   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}}));
755
756   // does not permit invoking class bar
757   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"bar", true, false, false}}));
758   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"bar", false, true, false}}));
759   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"bar", true, true, false}}));
760
761   // allows class bar if it is whitelisted
762   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"bar", true, false, true}}));
763   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"bar", false, true, true}}));
764   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"bar", true, true, true}}));
765 }
766
767 TEST(OSDCap, AllowClassMulti) {
768   OSDCap cap;
769   ASSERT_TRUE(cap.parse("allow class foo", NULL));
770
771   // can call any method on foo, but not bar, so the entire op is rejected
772   // bar with whitelist is rejected because it still needs rwx/class-read,write
773   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", true, true, true}}));
774   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", true, true, false}}));
775   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", true, false, true}}));
776   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", true, false, false}}));
777   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", false, true, true}}));
778   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", false, true, false}}));
779   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", false, false, false}}));
780
781   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", true, true, true}}));
782   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", true, true, false}}));
783   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", true, false, true}}));
784   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", true, false, false}}));
785   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", false, true, true}}));
786   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", false, true, false}}));
787   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", false, false, false}}));
788
789   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", true, true, true}}));
790   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", true, true, false}}));
791   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", true, false, true}}));
792   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", true, false, false}}));
793   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", false, true, true}}));
794   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", false, true, false}}));
795   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", false, false, false}}));
796
797   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", true, true, true}}));
798   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", true, true, false}}));
799   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", true, false, true}}));
800   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", true, false, false}}));
801   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", false, true, true}}));
802   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", false, true, false}}));
803   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", false, false, false}}));
804
805   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", true, true, true}}));
806   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", true, true, false}}));
807   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", true, false, true}}));
808   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", true, false, false}}));
809   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", false, true, true}}));
810   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", false, true, false}}));
811   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", false, false, false}}));
812
813   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", true, true, true}}));
814   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", true, true, false}}));
815   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", true, false, true}}));
816   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", true, false, false}}));
817   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", false, true, true}}));
818   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", false, true, false}}));
819   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", false, false, false}}));
820
821   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", true, true, true}}));
822   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", true, true, false}}));
823   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", true, false, true}}));
824   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", true, false, false}}));
825   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", false, true, true}}));
826   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", false, true, false}}));
827   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", false, false, false}}));
828
829   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", true, true, true}}));
830   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", true, true, false}}));
831   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", true, false, true}}));
832   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", true, false, false}}));
833   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", false, true, true}}));
834   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", false, true, false}}));
835   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", false, false, false}}));
836
837   // these are OK because 'bar' is on the whitelist BUT the calls don't read or write
838   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", false, false, true}}));
839   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", false, false, true}}));
840   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", false, false, true}}));
841   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", false, false, true}}));
842   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", false, false, true}}));
843   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", false, false, true}}));
844   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", false, false, true}}));
845   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", false, false, true}}));
846
847   // can call any method on foo or bar regardless of whitelist status
848   OSDCap cap2;
849   ASSERT_TRUE(cap2.parse("allow class foo, allow class bar", NULL));
850
851   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", true, true, true}}));
852   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", true, true, false}}));
853   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", true, false, true}}));
854   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", true, false, false}}));
855   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", false, true, true}}));
856   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", false, true, false}}));
857   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", false, false, true}}));
858   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", false, false, false}}));
859
860   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", true, true, true}}));
861   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", true, true, false}}));
862   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", true, false, true}}));
863   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", true, false, false}}));
864   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", false, true, true}}));
865   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", false, true, false}}));
866   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", false, false, true}}));
867   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", false, false, false}}));
868
869   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", true, true, true}}));
870   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", true, true, false}}));
871   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", true, false, true}}));
872   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", true, false, false}}));
873   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", false, true, true}}));
874   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", false, true, false}}));
875   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", false, false, true}}));
876   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", false, false, false}}));
877
878   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", true, true, true}}));
879   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", true, true, false}}));
880   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", true, false, true}}));
881   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", true, false, false}}));
882   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", false, true, true}}));
883   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", false, true, false}}));
884   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", false, false, true}}));
885   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", false, false, false}}));
886
887   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", true, true, true}}));
888   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", true, true, false}}));
889   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", true, false, true}}));
890   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", true, false, false}}));
891   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", false, true, true}}));
892   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", false, true, false}}));
893   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", false, false, true}}));
894   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", false, false, false}}));
895
896   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", true, true, true}}));
897   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", true, true, false}}));
898   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", true, false, true}}));
899   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", true, false, false}}));
900   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", false, true, true}}));
901   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", false, true, false}}));
902   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", false, false, true}}));
903   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", false, false, false}}));
904
905   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", true, true, true}}));
906   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", true, true, false}}));
907   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", true, false, true}}));
908   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", true, false, false}}));
909   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", false, true, true}}));
910   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", false, true, false}}));
911   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", false, false, true}}));
912   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", false, false, false}}));
913
914   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", true, true, true}}));
915   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", true, true, false}}));
916   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", true, false, true}}));
917   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", true, false, false}}));
918   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", false, true, true}}));
919   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", false, true, false}}));
920   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", false, false, true}}));
921   ASSERT_TRUE(cap2.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", false, false, false}}));
922 }
923
924 TEST(OSDCap, AllowClassMultiRWX) {
925   OSDCap cap;
926   ASSERT_TRUE(cap.parse("allow rwx, allow class foo", NULL));
927
928   // can call anything on foo, but only whitelisted methods on bar
929   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", true, true, true}}));
930   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", true, false, true}}));
931   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", false, true, true}}));
932   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", false, false, true}}));
933
934   // fails because bar not whitelisted
935   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", true, true, false}}));
936   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", true, false, false}}));
937   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", false, true, false}}));
938   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, true}, {"bar", false, false, false}}));
939
940   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", true, true, true}}));
941   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", true, false, true}}));
942   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", false, true, true}}));
943   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", false, false, true}}));
944
945   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", true, true, false}}));
946   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", true, false, false}}));
947   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", false, true, false}}));
948   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, true, false}, {"bar", false, false, false}}));
949
950   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", true, true, true}}));
951   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", true, false, true}}));
952   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", false, true, true}}));
953   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", false, false, true}}));
954
955   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", true, true, false}}));
956   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", true, false, false}}));
957   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", false, true, false}}));
958   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, true}, {"bar", false, false, false}}));
959
960   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", true, true, true}}));
961   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", true, false, true}}));
962   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", false, true, true}}));
963   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", false, false, true}}));
964
965   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", true, true, false}}));
966   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", true, false, false}}));
967   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", false, true, false}}));
968   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", true, false, false}, {"bar", false, false, false}}));
969
970   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", true, true, true}}));
971   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", true, false, true}}));
972   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", false, true, true}}));
973   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", false, false, true}}));
974
975   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", true, true, false}}));
976   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", true, false, false}}));
977   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", false, true, false}}));
978   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, true}, {"bar", false, false, false}}));
979
980   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", true, true, true}}));
981   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", true, false, true}}));
982   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", false, true, true}}));
983   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", false, false, true}}));
984
985   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", true, true, false}}));
986   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", true, false, false}}));
987   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", false, true, false}}));
988   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, true, false}, {"bar", false, false, false}}));
989
990   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", true, true, true}}));
991   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", true, false, true}}));
992   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", false, true, true}}));
993   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", false, false, true}}));
994
995   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", true, true, false}}));
996   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", true, false, false}}));
997   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", false, true, false}}));
998   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, true}, {"bar", false, false, false}}));
999
1000   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", true, true, true}}));
1001   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", true, false, true}}));
1002   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", false, true, true}}));
1003   ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", false, false, true}}));
1004
1005   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", true, true, false}}));
1006   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", true, false, false}}));
1007   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", false, true, false}}));
1008   ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, {{"foo", false, false, false}, {"bar", false, false, false}}));
1009 }
1010
1011 TEST(OSDCap, AllowProfile) {
1012   OSDCap cap;
1013   ASSERT_TRUE(cap.parse("profile read-only, profile read-write pool abc", NULL));
1014   ASSERT_FALSE(cap.allow_all());
1015   ASSERT_FALSE(cap.is_capable("foo", "", 0, "asdf", true, true, {}));
1016   ASSERT_TRUE(cap.is_capable("foo", "", 0, "asdf", true, false, {}));
1017   ASSERT_TRUE(cap.is_capable("abc", "", 0, "asdf", false, true, {}));
1018
1019   // RBD
1020   cap.grants.clear();
1021   ASSERT_TRUE(cap.parse("profile rbd pool abc", NULL));
1022   ASSERT_FALSE(cap.allow_all());
1023   ASSERT_FALSE(cap.is_capable("foo", "", 0, "asdf", true, true, {}));
1024   ASSERT_FALSE(cap.is_capable("foo", "", 0, "rbd_children", true, false, {}));
1025   ASSERT_TRUE(cap.is_capable("foo", "", 0, "rbd_children", false, false,
1026                              {{"rbd", true, false, true}}));
1027   ASSERT_TRUE(cap.is_capable("abc", "", 0, "asdf", true, true,
1028                              {{"rbd", true, true, true}}));
1029
1030   cap.grants.clear();
1031   ASSERT_TRUE(cap.parse("profile rbd-read-only pool abc", NULL));
1032   ASSERT_FALSE(cap.allow_all());
1033   ASSERT_FALSE(cap.is_capable("foo", "", 0, "rbd_children", true, false, {}));
1034   ASSERT_TRUE(cap.is_capable("abc", "", 0, "asdf", true, false,
1035                              {{"rbd", true, false, true}}));
1036 }
1037