11d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich/* lib_test.c -- simple libcap-ng test suite
21d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * Copyright 2009,2012 Red Hat Inc., Durham, North Carolina.
31d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * All Rights Reserved.
41d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich *
51d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * This library is free software; you can redistribute it and/or
61d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * modify it under the terms of the GNU Lesser General Public
71d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * License as published by the Free Software Foundation; either
81d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * version 2.1 of the License, or (at your option) any later version.
91d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich *
101d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * This library is distributed in the hope that it will be useful,
111d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * but WITHOUT ANY WARRANTY; without even the implied warranty of
121d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
131d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * Lesser General Public License for more details.
141d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich *
151d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * You should have received a copy of the GNU Lesser General Public
161d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * License along with this library; if not, write to the Free Software
171d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
181d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich *
191d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * Authors:
201d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich *      Steve Grubb <sgrubb@redhat.com>
211d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich */
221d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich
231d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include "config.h"
241d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include "../cap-ng.h"
251d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include <stdlib.h>
261d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include <stdio.h>
271d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include <string.h>
281d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich
291d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich
301d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichint main(void)
311d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{
321d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich	int rc, i, len, last = CAP_LAST_CAP;
331d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich	char *text;
341d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich	void *saved;
351d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich
361d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich	puts("Doing basic bit tests...");
371d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich	capng_clear(CAPNG_SELECT_BOTH);
381d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich	if (capng_have_capabilities(CAPNG_SELECT_BOTH) != CAPNG_NONE) {
391d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		puts("Failed clearing capabilities");
401d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		abort();
411d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich	}
421d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich	saved = capng_save_state();
431d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich	capng_fill(CAPNG_SELECT_BOTH);
441d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich	if (capng_have_capabilities(CAPNG_SELECT_BOTH) != CAPNG_FULL) {
451d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		puts("Failed filling capabilities");
461d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		abort();
471d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich	}
481d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich	// Need to detect if version 1 or 2 capabilities
491d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich	text = capng_print_caps_numeric(CAPNG_PRINT_BUFFER, CAPNG_SELECT_CAPS);
501d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich	len = strlen(text);
511d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich	free(text);
521d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich	if (len < 80 && last > 30)	// The kernel & headers are mismatched
531d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		last = 30;
541d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich	// Now test that restore still works
551d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich	capng_restore_state(&saved);
561d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich	if (capng_have_capabilities(CAPNG_SELECT_BOTH) != CAPNG_NONE) {
571d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		puts("Failed restoring capabilities");
581d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		abort();
591d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich	}
601d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich	printf("Doing advanced bit tests for %d capabilities...\n", last);
611d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich	for (i=0; i<=last; i++) {
621d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		const char *name;
631d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		capng_clear(CAPNG_SELECT_BOTH);
641d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		rc = capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, i);
651d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		if (rc) {
661d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich			puts("Failed update test 1");
671d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich			abort();
681d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		}
691d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		rc = capng_have_capability(CAPNG_EFFECTIVE, i);
701d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		if (rc == 0) {
711d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich			puts("Failed have capability test 1");
721d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich			capng_print_caps_numeric(CAPNG_PRINT_STDOUT,
731d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich					CAPNG_SELECT_CAPS);
741d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich			abort();
751d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		}
761d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		if(capng_have_capabilities(CAPNG_SELECT_CAPS)!=CAPNG_PARTIAL){
771d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich			puts("Failed have capabilities test 1");
781d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich			capng_print_caps_numeric(CAPNG_PRINT_STDOUT,
791d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich					CAPNG_SELECT_CAPS);
801d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich			abort();
811d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		}
821d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#if CAP_LAST_CAP > 31
831d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		rc = capng_update(CAPNG_ADD, CAPNG_BOUNDING_SET, i);
841d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		if (rc) {
851d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich			puts("Failed bset update test 2");
861d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich			abort();
871d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		}
881d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		rc = capng_have_capability(CAPNG_BOUNDING_SET, i);
891d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		if (rc == 0) {
901d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich			puts("Failed bset have capability test 2");
911d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich			capng_print_caps_numeric(CAPNG_PRINT_STDOUT,
921d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich					CAPNG_SELECT_BOTH);
931d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich			abort();
941d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		}
951d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		if(capng_have_capabilities(CAPNG_SELECT_BOUNDS)!=CAPNG_PARTIAL){
961d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich			puts("Failed bset have capabilities test 2");
971d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich			capng_print_caps_numeric(CAPNG_PRINT_STDOUT,
981d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich					CAPNG_SELECT_BOTH);
991d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich			abort();
1001d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		}
1011d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif
1021d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		text=capng_print_caps_text(CAPNG_PRINT_BUFFER, CAPNG_EFFECTIVE);
1031d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		if (text == NULL) {
1041d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich			puts("Failed getting print text to buffer");
1051d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich			abort();
1061d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		}
1071d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		name = capng_capability_to_name(i);
1081d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		if (name == NULL) {
1091d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich			printf("Failed converting capability %d to name\n", i);
1101d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich			abort();
1111d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		}
1121d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		if (strcmp(text, name)) {
1131d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich			puts("Failed print text comparison");
1141d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich			printf("%s != %s\n", text, name);
1151d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich			abort();
1161d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		}
1171d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		free(text);
1181d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		// Now make sure the mask part is working
1191d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		capng_fill(CAPNG_SELECT_BOTH);
1201d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		rc = capng_update(CAPNG_DROP, CAPNG_EFFECTIVE, i);
1211d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		if (rc) {
1221d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich			puts("Failed update test 3");
1231d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich			abort();
1241d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		}
1251d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		// Should be partial
1261d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		if(capng_have_capabilities(CAPNG_SELECT_CAPS)!=CAPNG_PARTIAL){
1271d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich			puts("Failed have capabilities test 3");
1281d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich			capng_print_caps_numeric(CAPNG_PRINT_STDOUT,
1291d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich					CAPNG_SELECT_CAPS);
1301d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich			abort();
1311d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		}
1321d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		// Add back the bit and should be full capabilities
1331d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		rc = capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, i);
1341d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		if (rc) {
1351d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich			puts("Failed update test 4");
1361d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich			abort();
1371d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		}
1381d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		if (capng_have_capabilities(CAPNG_SELECT_CAPS) != CAPNG_FULL){
1391d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich			puts("Failed have capabilities test 4");
1401d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich			capng_print_caps_numeric(CAPNG_PRINT_STDOUT,
1411d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich					CAPNG_SELECT_CAPS);
1421d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich			abort();
1431d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		}
1441d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich	}
1451d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich	// Now test the updatev function
1461d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich	capng_clear(CAPNG_SELECT_BOTH);
1471d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich	rc = capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE,
1481d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich			CAP_CHOWN, CAP_FOWNER, CAP_KILL, -1);
1491d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich	if (rc) {
1501d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		puts("Failed updatev test");
1511d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		abort();
1521d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich	}
1531d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich	rc = capng_have_capability(CAPNG_EFFECTIVE, CAP_CHOWN) &&
1541d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		capng_have_capability(CAPNG_EFFECTIVE, CAP_FOWNER) &&
1551d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		capng_have_capability(CAPNG_EFFECTIVE, CAP_KILL);
1561d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich	if (rc == 0) {
1571d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		puts("Failed have updatev capability test");
1581d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		capng_print_caps_numeric(CAPNG_PRINT_STDOUT,
1591d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich				CAPNG_SELECT_CAPS);
1601d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich		abort();
1611d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich	}
1621d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich
1631d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich	return EXIT_SUCCESS;
1641d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich}
1651d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich
166