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
30int 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