1 /* lib_test.c -- simple libcap-ng test suite
2  * Copyright 2009,2012 Red Hat Inc., Durham, North Carolina.
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
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  * Authors:
20  *      Steve Grubb <sgrubb@redhat.com>
21  */
22 
23 #include "config.h"
24 #include "../cap-ng.h"
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <string.h>
28 
29 
main(void)30 int main(void)
31 {
32 	int rc, i, len, last = CAP_LAST_CAP;
33 	char *text;
34 	void *saved;
35 
36 	puts("Doing basic bit tests...");
37 	capng_clear(CAPNG_SELECT_BOTH);
38 	if (capng_have_capabilities(CAPNG_SELECT_BOTH) != CAPNG_NONE) {
39 		puts("Failed clearing capabilities");
40 		abort();
41 	}
42 	saved = capng_save_state();
43 	capng_fill(CAPNG_SELECT_BOTH);
44 	if (capng_have_capabilities(CAPNG_SELECT_BOTH) != CAPNG_FULL) {
45 		puts("Failed filling capabilities");
46 		abort();
47 	}
48 	// Need to detect if version 1 or 2 capabilities
49 	text = capng_print_caps_numeric(CAPNG_PRINT_BUFFER, CAPNG_SELECT_CAPS);
50 	len = strlen(text);
51 	free(text);
52 	if (len < 80 && last > 30)	// The kernel & headers are mismatched
53 		last = 30;
54 	// Now test that restore still works
55 	capng_restore_state(&saved);
56 	if (capng_have_capabilities(CAPNG_SELECT_BOTH) != CAPNG_NONE) {
57 		puts("Failed restoring capabilities");
58 		abort();
59 	}
60 	printf("Doing advanced bit tests for %d capabilities...\n", last);
61 	for (i=0; i<=last; i++) {
62 		const char *name;
63 		capng_clear(CAPNG_SELECT_BOTH);
64 		rc = capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, i);
65 		if (rc) {
66 			puts("Failed update test 1");
67 			abort();
68 		}
69 		rc = capng_have_capability(CAPNG_EFFECTIVE, i);
70 		if (rc == 0) {
71 			puts("Failed have capability test 1");
72 			capng_print_caps_numeric(CAPNG_PRINT_STDOUT,
73 					CAPNG_SELECT_CAPS);
74 			abort();
75 		}
76 		if(capng_have_capabilities(CAPNG_SELECT_CAPS)!=CAPNG_PARTIAL){
77 			puts("Failed have capabilities test 1");
78 			capng_print_caps_numeric(CAPNG_PRINT_STDOUT,
79 					CAPNG_SELECT_CAPS);
80 			abort();
81 		}
82 #if CAP_LAST_CAP > 31
83 		rc = capng_update(CAPNG_ADD, CAPNG_BOUNDING_SET, i);
84 		if (rc) {
85 			puts("Failed bset update test 2");
86 			abort();
87 		}
88 		rc = capng_have_capability(CAPNG_BOUNDING_SET, i);
89 		if (rc == 0) {
90 			puts("Failed bset have capability test 2");
91 			capng_print_caps_numeric(CAPNG_PRINT_STDOUT,
92 					CAPNG_SELECT_BOTH);
93 			abort();
94 		}
95 		if(capng_have_capabilities(CAPNG_SELECT_BOUNDS)!=CAPNG_PARTIAL){
96 			puts("Failed bset have capabilities test 2");
97 			capng_print_caps_numeric(CAPNG_PRINT_STDOUT,
98 					CAPNG_SELECT_BOTH);
99 			abort();
100 		}
101 #endif
102 		text=capng_print_caps_text(CAPNG_PRINT_BUFFER, CAPNG_EFFECTIVE);
103 		if (text == NULL) {
104 			puts("Failed getting print text to buffer");
105 			abort();
106 		}
107 		name = capng_capability_to_name(i);
108 		if (name == NULL) {
109 			printf("Failed converting capability %d to name\n", i);
110 			abort();
111 		}
112 		if (strcmp(text, name)) {
113 			puts("Failed print text comparison");
114 			printf("%s != %s\n", text, name);
115 			abort();
116 		}
117 		free(text);
118 		// Now make sure the mask part is working
119 		capng_fill(CAPNG_SELECT_BOTH);
120 		rc = capng_update(CAPNG_DROP, CAPNG_EFFECTIVE, i);
121 		if (rc) {
122 			puts("Failed update test 3");
123 			abort();
124 		}
125 		// Should be partial
126 		if(capng_have_capabilities(CAPNG_SELECT_CAPS)!=CAPNG_PARTIAL){
127 			puts("Failed have capabilities test 3");
128 			capng_print_caps_numeric(CAPNG_PRINT_STDOUT,
129 					CAPNG_SELECT_CAPS);
130 			abort();
131 		}
132 		// Add back the bit and should be full capabilities
133 		rc = capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, i);
134 		if (rc) {
135 			puts("Failed update test 4");
136 			abort();
137 		}
138 		if (capng_have_capabilities(CAPNG_SELECT_CAPS) != CAPNG_FULL){
139 			puts("Failed have capabilities test 4");
140 			capng_print_caps_numeric(CAPNG_PRINT_STDOUT,
141 					CAPNG_SELECT_CAPS);
142 			abort();
143 		}
144 	}
145 	// Now test the updatev function
146 	capng_clear(CAPNG_SELECT_BOTH);
147 	rc = capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE,
148 			CAP_CHOWN, CAP_FOWNER, CAP_KILL, -1);
149 	if (rc) {
150 		puts("Failed updatev test");
151 		abort();
152 	}
153 	rc = capng_have_capability(CAPNG_EFFECTIVE, CAP_CHOWN) &&
154 		capng_have_capability(CAPNG_EFFECTIVE, CAP_FOWNER) &&
155 		capng_have_capability(CAPNG_EFFECTIVE, CAP_KILL);
156 	if (rc == 0) {
157 		puts("Failed have updatev capability test");
158 		capng_print_caps_numeric(CAPNG_PRINT_STDOUT,
159 				CAPNG_SELECT_CAPS);
160 		abort();
161 	}
162 
163 	return EXIT_SUCCESS;
164 }
165 
166