1 /* lib_test.c -- simple libcap-ng test suite
2 * Copyright 2009,2012-13 Red Hat Inc.
3 * All Rights Reserved.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this program; see the file COPYING.LIB. If not, write to the
17 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor
18 * Boston, MA 02110-1335, USA.
19 *
20 * Authors:
21 * Steve Grubb <[email protected]>
22 */
23
24 #include "config.h"
25 #include "../cap-ng.h"
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <string.h>
29 #include <errno.h>
30 #include <fcntl.h>
31 #include <sys/stat.h>
32
get_last_cap(void)33 static unsigned int get_last_cap(void)
34 {
35 int fd;
36
37 fd = open("/proc/sys/kernel/cap_last_cap", O_RDONLY);
38 if (fd == -1) {
39 return CAP_LAST_CAP;
40 } else {
41 char buf[8];
42 int num = read(fd, buf, sizeof(buf));
43 if (num > 0) {
44 errno = 0;
45 unsigned int val = strtoul(buf, NULL, 10);
46 if (errno == 0)
47 return val;
48 }
49 close(fd);
50 }
51 return CAP_LAST_CAP;
52 }
53
main(void)54 int main(void)
55 {
56 int rc;
57 unsigned int i, len, last = get_last_cap();
58 char *text;
59 void *saved;
60
61 puts("Doing basic bit tests...");
62 capng_clear(CAPNG_SELECT_BOTH);
63 if (capng_have_capabilities(CAPNG_SELECT_BOTH) != CAPNG_NONE) {
64 puts("Failed clearing capabilities");
65 abort();
66 }
67 saved = capng_save_state();
68 capng_fill(CAPNG_SELECT_BOTH);
69 if (capng_have_capabilities(CAPNG_SELECT_BOTH) != CAPNG_FULL) {
70 puts("Failed filling capabilities");
71 abort();
72 }
73 // Need to detect if version 1 or 2 capabilities
74 text = capng_print_caps_numeric(CAPNG_PRINT_BUFFER, CAPNG_SELECT_CAPS);
75 len = strlen(text);
76 free(text);
77 if (len < 80 && last > 30) // The kernel & headers are mismatched
78 last = 30;
79 // Now test that restore still works
80 capng_restore_state(&saved);
81 if (capng_have_capabilities(CAPNG_SELECT_BOTH) != CAPNG_NONE) {
82 puts("Failed restoring capabilities");
83 abort();
84 }
85 printf("Doing advanced bit tests for %d capabilities...\n", last);
86 for (i=0; i<=last; i++) {
87 const char *name;
88 capng_clear(CAPNG_SELECT_BOTH);
89 rc = capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, i);
90 if (rc) {
91 puts("Failed update test 1");
92 abort();
93 }
94 rc = capng_have_capability(CAPNG_EFFECTIVE, i);
95 if (rc == 0) {
96 puts("Failed have capability test 1");
97 capng_print_caps_numeric(CAPNG_PRINT_STDOUT,
98 CAPNG_SELECT_CAPS);
99 abort();
100 }
101 if(capng_have_capabilities(CAPNG_SELECT_CAPS)!=CAPNG_PARTIAL){
102 puts("Failed have capabilities test 1");
103 capng_print_caps_numeric(CAPNG_PRINT_STDOUT,
104 CAPNG_SELECT_CAPS);
105 abort();
106 }
107 #if CAP_LAST_CAP > 31
108 rc = capng_update(CAPNG_ADD, CAPNG_BOUNDING_SET, i);
109 if (rc) {
110 puts("Failed bset update test 2");
111 abort();
112 }
113 rc = capng_have_capability(CAPNG_BOUNDING_SET, i);
114 if (rc == 0) {
115 puts("Failed bset have capability test 2");
116 capng_print_caps_numeric(CAPNG_PRINT_STDOUT,
117 CAPNG_SELECT_BOTH);
118 abort();
119 }
120 if(capng_have_capabilities(CAPNG_SELECT_BOUNDS)!=CAPNG_PARTIAL){
121 puts("Failed bset have capabilities test 2");
122 capng_print_caps_numeric(CAPNG_PRINT_STDOUT,
123 CAPNG_SELECT_BOTH);
124 abort();
125 }
126 #endif
127 text=capng_print_caps_text(CAPNG_PRINT_BUFFER, CAPNG_EFFECTIVE);
128 if (text == NULL) {
129 puts("Failed getting print text to buffer");
130 abort();
131 }
132 name = capng_capability_to_name(i);
133 if (name == NULL) {
134 printf("Failed converting capability %d to name\n", i);
135 abort();
136 }
137 if (strcmp(text, name)) {
138 puts("Failed print text comparison");
139 printf("%s != %s\n", text, name);
140 abort();
141 }
142 free(text);
143 // Now make sure the mask part is working
144 capng_fill(CAPNG_SELECT_BOTH);
145 rc = capng_update(CAPNG_DROP, CAPNG_EFFECTIVE, i);
146 if (rc) {
147 puts("Failed update test 3");
148 abort();
149 }
150 // Should be partial
151 if(capng_have_capabilities(CAPNG_SELECT_CAPS)!=CAPNG_PARTIAL){
152 puts("Failed have capabilities test 3");
153 capng_print_caps_numeric(CAPNG_PRINT_STDOUT,
154 CAPNG_SELECT_CAPS);
155 abort();
156 }
157 // Add back the bit and should be full capabilities
158 rc = capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, i);
159 if (rc) {
160 puts("Failed update test 4");
161 abort();
162 }
163 if (capng_have_capabilities(CAPNG_SELECT_CAPS) != CAPNG_FULL){
164 puts("Failed have capabilities test 4");
165 capng_print_caps_numeric(CAPNG_PRINT_STDOUT,
166 CAPNG_SELECT_CAPS);
167 abort();
168 }
169 }
170 // Now test the updatev function
171 capng_clear(CAPNG_SELECT_BOTH);
172 rc = capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE,
173 CAP_CHOWN, CAP_FOWNER, CAP_KILL, -1);
174 if (rc) {
175 puts("Failed updatev test");
176 abort();
177 }
178 rc = capng_have_capability(CAPNG_EFFECTIVE, CAP_CHOWN) &&
179 capng_have_capability(CAPNG_EFFECTIVE, CAP_FOWNER) &&
180 capng_have_capability(CAPNG_EFFECTIVE, CAP_KILL);
181 if (rc == 0) {
182 puts("Failed have updatev capability test");
183 capng_print_caps_numeric(CAPNG_PRINT_STDOUT,
184 CAPNG_SELECT_CAPS);
185 abort();
186 }
187
188 return EXIT_SUCCESS;
189 }
190
191