11d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich/* 21d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * captest.c - A program that demonstrates and outputs capabilities 31d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * Copyright (c) 2009 Red Hat Inc., Durham, North Carolina. 41d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * All Rights Reserved. 51d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * 61d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * This software may be freely redistributed and/or modified under the 71d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * terms of the GNU General Public License as published by the Free 81d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * Software Foundation; either version 2, or (at your option) any 91d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * later version. 101d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * 111d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * This program is distributed in the hope that it will be useful, 121d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * but WITHOUT ANY WARRANTY; without even the implied warranty of 131d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 141d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * GNU General Public License for more details. 151d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * 161d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * You should have received a copy of the GNU General Public License 171d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * along with this program; see the file COPYING. If not, write to the 181d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 191d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * 201d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * Authors: 211d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * Steve Grubb <sgrubb@redhat.com> 221d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * 231d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich */ 241d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include "config.h" 251d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include <unistd.h> 261d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include <stdio.h> 271d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include <fcntl.h> 281d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include <stdlib.h> 291d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include <string.h> 301d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include <errno.h> 311d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include <cap-ng.h> 321d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include <sys/prctl.h> 331d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifdef HAVE_LINUX_SECUREBITS_H 341d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include <linux/securebits.h> 351d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 361d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 371d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich/* children can't get caps back */ 381d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifndef SECURE_NOROOT 391d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#define SECURE_NOROOT 0 401d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 411d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifndef SECURE_NOROOT_LOCKED 421d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#define SECURE_NOROOT_LOCKED 1 /* make bit-0 immutable */ 431d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 441d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich/* Setuid apps run by uid 0 don't get caps back */ 451d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifndef SECURE_NO_SETUID_FIXUP 461d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#define SECURE_NO_SETUID_FIXUP 2 471d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 481d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifndef SECURE_NO_SETUID_FIXUP_LOCKED 491d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#define SECURE_NO_SETUID_FIXUP_LOCKED 3 /* make bit-2 immutable */ 501d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 511d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 521d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstatic int text = 0, no_child = 0, lock = 0; 531d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 541d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstatic void report(void) 551d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 561d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich int rc, escalated = 0, need_comma = 0; 571d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich uid_t uid, euid, suid; 581d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich gid_t gid, egid, sgid; 591d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 601d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich // Refresh what we have for capabilities 611d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (capng_get_caps_process()) { 621d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("Error getting capabilities\n"); 631d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich exit(1); 641d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 651d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 661d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich // Check user credentials 671d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich getresuid(&uid, &euid, &suid); 681d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich getresgid(&gid, &egid, &sgid); 691d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (no_child) { 701d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if ((uid != euid && uid != 0) || 711d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich capng_have_capability(CAPNG_EFFECTIVE, 721d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich CAP_SETUID)) { 731d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("Attempting to regain root..."); 741d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich setuid(0); 751d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich getresuid(&uid, &euid, &suid); 761d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (uid == 0) { 771d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("SUCCESS - PRIVILEGE ESCALATION POSSIBLE\n"); 781d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich setgid(0); 791d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich getresgid(&gid, &egid, &sgid); 801d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich escalated = 1; 811d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } else 821d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("FAILED\n"); 831d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 841d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("Child "); 851d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 861d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("User credentials uid:%d euid:%d suid:%d\n", uid, euid, suid); 871d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (no_child) 881d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("Child "); 891d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("Group credentials gid:%d egid:%d sgid:%d\n", gid, egid, sgid); 901d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (uid != euid || gid != egid) 911d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("Note: app has mismatching credentials!!\n"); 921d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 931d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich // Check capabilities 941d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (text) { 951d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (capng_have_capabilities(CAPNG_SELECT_CAPS) == CAPNG_NONE) { 961d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (no_child) 971d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("Child capabilities: none\n"); 981d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else 991d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("Current capabilities: none\n"); 1001d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } else { 1011d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (no_child) 1021d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("Child "); 1031d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("Effective: "); 1041d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich capng_print_caps_text(CAPNG_PRINT_STDOUT, 1051d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich CAPNG_EFFECTIVE); 1061d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("\n"); 1071d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (no_child) 1081d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("Child "); 1091d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("Permitted: "); 1101d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich capng_print_caps_text(CAPNG_PRINT_STDOUT, 1111d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich CAPNG_PERMITTED); 1121d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("\n"); 1131d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (no_child) 1141d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("Child "); 1151d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("Inheritable: "); 1161d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich capng_print_caps_text(CAPNG_PRINT_STDOUT, 1171d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich CAPNG_INHERITABLE); 1181d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("\n"); 1191d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (no_child) 1201d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("Child "); 1211d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("Bounding Set: "); 1221d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich capng_print_caps_text(CAPNG_PRINT_STDOUT, 1231d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich CAPNG_BOUNDING_SET); 1241d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("\n"); 1251d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 1261d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } else { 1271d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (capng_have_capabilities(CAPNG_SELECT_CAPS) == CAPNG_NONE) { 1281d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (no_child) 1291d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("Child capabilities: none\n"); 1301d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else 1311d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("Current capabilities: none\n"); 1321d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } else { 1331d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (no_child) 1341d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("Child capabilities:\n"); 1351d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich capng_print_caps_numeric(CAPNG_PRINT_STDOUT, 1361d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich CAPNG_SELECT_BOTH); 1371d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 1381d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 1391d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 1401d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich // Now check securebits flags 1411d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifdef PR_SET_SECUREBITS 1421d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (no_child) 1431d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("Child "); 1441d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("securebits flags: "); 1451d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich rc = prctl(PR_GET_SECUREBITS, 1 << SECURE_NOROOT); 1461d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (rc & (1 << SECURE_NOROOT)) { 1471d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("NOROOT"); 1481d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich need_comma = 1; 1491d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 1501d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich rc = prctl(PR_GET_SECUREBITS, 1 << SECURE_NOROOT_LOCKED); 1511d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (rc & (1 << SECURE_NOROOT_LOCKED)) { 1521d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (need_comma) 1531d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf(", "); 1541d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("NOROOT_LOCKED"); 1551d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich need_comma = 1; 1561d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 1571d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich rc = prctl(PR_GET_SECUREBITS, 1 << SECURE_NO_SETUID_FIXUP); 1581d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (rc & (1 << SECURE_NO_SETUID_FIXUP)) { 1591d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (need_comma) 1601d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf(", "); 1611d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("NO_SETUID_FIXUP"); 1621d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich need_comma = 1; 1631d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 1641d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich rc = prctl(PR_GET_SECUREBITS, 1 << SECURE_NO_SETUID_FIXUP_LOCKED); 1651d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (rc & (1 << SECURE_NO_SETUID_FIXUP_LOCKED)) { 1661d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (need_comma) 1671d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf(", "); 1681d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("NO_SETUID_FIXUP_LOCKED"); 1691d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich need_comma = 1; 1701d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 1711d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (need_comma == 0) 1721d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("none"); 1731d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("\n"); 1741d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 1751d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich // Now do child process checks 1761d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (no_child == 0 || escalated) { 1771d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("Attempting direct access to shadow..."); 1781d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (access("/etc/shadow", R_OK) == 0) 1791d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("SUCCESS\n"); 1801d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else 1811d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("FAILED (%s)\n", strerror(errno)); 1821d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 1831d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (no_child == 0) { 1841d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("Attempting to access shadow by child process..."); 1851d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich rc = system("cat /etc/shadow > /dev/null 2>&1"); 1861d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (rc == 0) 1871d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("SUCCESS\n"); 1881d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else 1891d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("FAILED\n"); 1901d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (text) 1911d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich system("/usr/bin/captest --no-child --text"); 1921d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else 1931d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich system("/usr/bin/captest --no-child"); 1941d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 1951d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 1961d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 1971d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstatic void usage(void) 1981d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 1991d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("usage: captest [ --drop-all | --drop-caps | --id ] [ --lock ] [ --text ]\n"); 2001d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 2011d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 2021d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichint main(int argc, char *argv[]) 2031d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 2041d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich int which = 0, i; 2051d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 2061d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich for (i = 1; i < argc; i++) { 2071d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (strcmp(argv[i], "--text") == 0) 2081d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich text = 1; 2091d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else if (strcmp(argv[i], "--no-child") == 0) 2101d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich no_child = 1; 2111d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else if (strcmp(argv[i], "--lock") == 0) 2121d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich lock = 1; 2131d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else if (strcmp(argv[i], "--drop-all") == 0) 2141d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich which = 1; 2151d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else if (strcmp(argv[i], "--drop-caps") == 0) 2161d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich which = 2; 2171d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else if (strcmp(argv[i], "--id") == 0) 2181d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich which = 3; 2191d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else { 2201d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich usage(); 2211d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return 0; 2221d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 2231d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 2241d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich switch (which) 2251d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich { 2261d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich case 1: 2271d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich capng_clear(CAPNG_SELECT_BOTH); 2281d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (lock) 2291d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich capng_lock(); 2301d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich capng_apply(CAPNG_SELECT_BOTH); 2311d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich report(); 2321d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich break; 2331d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich case 2: 2341d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich capng_clear(CAPNG_SELECT_CAPS); 2351d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (lock) 2361d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich capng_lock(); 2371d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich capng_apply(CAPNG_SELECT_CAPS); 2381d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich report(); 2391d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich break; 2401d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich case 3: { 2411d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich int rc; 2421d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 2431d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich capng_clear(CAPNG_SELECT_BOTH); 2441d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich capng_update(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED, 2451d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich CAP_CHOWN); 2461d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich rc = capng_change_id(99, 99, 2471d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich CAPNG_DROP_SUPP_GRP | CAPNG_CLEAR_BOUNDING); 2481d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (rc < 0) { 2491d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("Error changing uid: %d\n", rc); 2501d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich capng_print_caps_text(CAPNG_PRINT_STDOUT, 2511d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich CAPNG_EFFECTIVE); 2521d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("\n"); 2531d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich exit(1); 2541d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 2551d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("Keeping CAP_CHOWN to show capabilities across uid change.\n"); 2561d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich report(); 2571d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } break; 2581d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich case 0: 2591d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (lock) 2601d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich capng_lock(); 2611d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich report(); 2621d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich break; 2631d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 2641d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return 0; 2651d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 2661d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 267