diff options
Diffstat (limited to 'progs/setcap.c')
-rw-r--r-- | progs/setcap.c | 93 |
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); } |