1/******************************************************************************/
2/*                                                                            */
3/* Copyright (c) International Business Machines  Corp., 2008                 */
4/*                                                                            */
5/* This program is free software;  you can redistribute it and/or modify      */
6/* it under the terms of the GNU General Public License as published by       */
7/* the Free Software Foundation; either version 2 of the License, or          */
8/* (at your option) any later version.                                        */
9/*                                                                            */
10/* This program 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                  */
13/* the GNU General Public License for more details.                           */
14/*                                                                            */
15/* You should have received a copy of the GNU General Public License          */
16/* along with this program;  if not, write to the Free Software               */
17/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA    */
18/*                                                                            */
19/******************************************************************************/
20/*
21 * File: inh_capped
22 * Author: Serge Hallyn
23 * Purpose: test that CAP_SETPCAP is needed to add bits to pI
24 * Uses no command line arguments.
25 */
26
27#include <stdio.h>
28#include "config.h"
29#if HAVE_SYS_CAPABILITY_H
30#include <linux/types.h>
31#include <sys/capability.h>
32#endif
33#include "test.h"
34
35char *TCID = "filecaps";
36int TST_TOTAL = 1;
37
38#ifdef HAVE_LIBCAP
39void debug_print_caps(char *when)
40{
41	char buf[2000];
42	tst_resm(TINFO, "%s", when);
43	snprintf(buf, 2000, "%s", cap_to_text(cap_get_proc(), NULL));
44	tst_resm(TINFO, "%s", buf);
45}
46
47int set_caps_from_text(char *capstr)
48{
49	cap_t caps = cap_from_text(capstr);
50	int ret;
51
52	if (!caps) {
53		tst_resm(TFAIL, "Bad capability name: %s\n", capstr);
54		return 1;
55	}
56	ret = cap_set_proc(caps);
57	cap_free(caps);
58	return ret;
59}
60#endif
61
62int main(void)
63{
64#ifdef HAVE_LIBCAP
65	int ret;
66
67	debug_print_caps("start");
68	ret = set_caps_from_text("all=eip");
69	debug_print_caps("after raising all caps");
70	if (ret) {
71		tst_brkm(TFAIL, NULL, "failed to raise all caps");
72	}
73
74	ret = set_caps_from_text("all=iep cap_sys_admin-iep");
75	debug_print_caps("after first drop cap_sys_admin");
76	if (ret) {
77		tst_brkm(TFAIL, NULL, "failed to drop capsysadmin from pI");
78	}
79
80	/* we can't regain cap_sys_admin in pE or pP, only pI */
81	ret = set_caps_from_text("all=eip cap_sys_admin-ep+i");
82	debug_print_caps("after first raise cap_sys_admin");
83	if (ret) {
84		tst_brkm(TFAIL, NULL, "failed to raise capsysadmin in pI");
85	}
86
87	ret = set_caps_from_text("all=ip cap_setpcap-e+ip cap_sys_admin+i-ep");
88	debug_print_caps("after drop cappset");
89	if (ret) {
90		tst_brkm(TFAIL, NULL, "failed to drop cappset from pE");
91	}
92
93	ret = set_caps_from_text("all=iep cap_sys_admin-iep cap_setpcap-e+ip");
94	debug_print_caps("after second drop cap_sys_admin");
95	if (ret) {
96		tst_brkm(TFAIL, NULL, "failed to drop capsysadmin from pI "
97			 "after dropping cappset from pE");
98	}
99
100	ret = set_caps_from_text("all=iep cap_sys_admin-ep+i cap_setpcap-e+ip");
101	debug_print_caps("final");
102	if (ret) {
103		tst_resm(TPASS, "pI is properly capped\n");
104		tst_exit();
105	}
106
107	tst_resm(TFAIL, "succeeded raising capsysadmin in pI "
108		 "without having setpcap");
109#else
110	tst_resm(TCONF, "System doesn't have POSIX capabilities support.");
111#endif
112	tst_exit();
113}
114