summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew G. Morgan <morgan@kernel.org>2008-10-23 22:13:13 -0700
committerAndrew G. Morgan <morgan@kernel.org>2008-10-23 22:13:13 -0700
commit9da338a75b5ae27e3f4226d214977a921d644e60 (patch)
treecb98d266449ffdabe48e10859a9e082cd6335b05
parent9f2e7c5245fc3100ed08d8a133f80afd88e81632 (diff)
downloadlibcap2-9da338a75b5ae27e3f4226d214977a921d644e60.tar.gz
Add a -v (verify) mode to setcap
This seems like a more logical place to put a verify capabilities than inventing a new program just for that purpose. Signed-off-by: Andrew G. Morgan <morgan@kernel.org>
-rw-r--r--progs/setcap.c93
1 files changed, 66 insertions, 27 deletions
diff --git a/progs/setcap.c b/progs/setcap.c
index 0501a9d..65a1cb4 100644
--- a/progs/setcap.c
+++ b/progs/setcap.c
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 1997,2007 Andrew G. Morgan <morgan@kernel.org>
+ * Copyright (c) 1997,2007-8 Andrew G. Morgan <morgan@kernel.org>
*
- * This sets the capabilities of a given file.
+ * This sets/verifies the capabilities of a given file.
*/
#include <errno.h>
@@ -14,7 +14,7 @@
static void usage(void)
{
fprintf(stderr,
- "usage: setcap [-q] (-r|-|<caps>) <filename> "
+ "usage: setcap [-q] [-v] (-r|-|<caps>) <filename> "
"[ ... (-r|-|<capsN>) <filenameN> ]\n"
"\n"
" Note <filename> must be a regular (non-symlink) file.\n"
@@ -58,8 +58,9 @@ static int read_caps(int quiet, const char *filename, char *buffer)
int main(int argc, char **argv)
{
+ int tried_to_cap_setfcap = 0;
char buffer[MAXCAP+1];
- int retval, quiet=0;
+ int retval, quiet=0, verify=0;
cap_t mycaps;
cap_value_t capflag;
@@ -71,31 +72,22 @@ int main(int argc, char **argv)
if (mycaps == NULL) {
fprintf(stderr, "warning - unable to get process capabilities"
" (old libcap?)\n");
- } else {
- capflag = CAP_SETFCAP;
-
- /*
- * Raise the effective CAP_SETPCAP.
- */
- if (cap_set_flag(mycaps, CAP_EFFECTIVE, 1, &capflag, CAP_SET) != 0) {
- perror("unable to manipulate CAP_SETFCAP - try a newer libcap?");
- exit(1);
- }
- if (cap_set_proc(mycaps) != 0) {
- perror("unable to set CAP_SETFCAP effective capability");
- exit(1);
- }
}
while (--argc > 0) {
const char *text;
cap_t cap_d;
- if (!strcmp(*++argv,"-q")) {
+ if (!strcmp(*++argv, "-q")) {
quiet = 1;
continue;
}
- if (!strcmp(*argv,"-r")) {
+ if (!strcmp(*argv, "-v")) {
+ verify = 1;
+ continue;
+ }
+
+ if (!strcmp(*argv, "-r")) {
cap_d = NULL;
} else {
if (!strcmp(*argv,"-")) {
@@ -125,17 +117,64 @@ int main(int argc, char **argv)
if (--argc <= 0)
usage();
-
/*
* Set the filesystem capability for this file.
*/
- retval = cap_set_file(*++argv, cap_d);
- if (retval != 0) {
- fprintf(stderr, "Failed to set capabilities on file `%s' (%s)\n",
- argv[0], strerror(errno));
- usage();
- }
+ if (verify) {
+ cap_t cap_on_file;
+ int cmp;
+ if (cap_d == NULL) {
+ cap_d = cap_from_text("=");
+ }
+
+ cap_on_file = cap_get_file(*++argv);
+
+ if (cap_on_file == NULL) {
+ cap_on_file = cap_from_text("=");
+ }
+
+ cmp = cap_compare(cap_on_file, cap_d);
+ cap_free(cap_on_file);
+
+ if (cmp != 0) {
+ if (!quiet) {
+ printf("%s differs in [%s%s%s]\n", *argv,
+ CAP_DIFFERS(cmp, CAP_PERMITTED) ? "p" : "",
+ CAP_DIFFERS(cmp, CAP_INHERITABLE) ? "i" : "",
+ CAP_DIFFERS(cmp, CAP_EFFECTIVE) ? "e" : "");
+ }
+ exit(1);
+ }
+ if (!quiet) {
+ printf("%s: OK\n", *argv);
+ }
+ } else {
+ if (!tried_to_cap_setfcap) {
+ capflag = CAP_SETFCAP;
+
+ /*
+ * Raise the effective CAP_SETFCAP.
+ */
+ if (cap_set_flag(mycaps, CAP_EFFECTIVE, 1, &capflag, CAP_SET)
+ != 0) {
+ perror("unable to manipulate CAP_SETFCAP - "
+ "try a newer libcap?");
+ exit(1);
+ }
+ if (cap_set_proc(mycaps) != 0) {
+ perror("unable to set CAP_SETFCAP effective capability");
+ exit(1);
+ }
+ }
+ retval = cap_set_file(*++argv, cap_d);
+ if (retval != 0) {
+ fprintf(stderr,
+ "Failed to set capabilities on file `%s' (%s)\n",
+ argv[0], strerror(errno));
+ usage();
+ }
+ }
if (cap_d) {
cap_free(cap_d);
}