diff options
author | Andrew Morgan <morgan@kernel.org> | 2007-07-18 00:02:08 -0700 |
---|---|---|
committer | Andrew Morgan <morgan@kernel.org> | 2007-08-13 23:33:12 -0700 |
commit | e6033df7d6f7f913a1807964b770daf7f3567d96 (patch) | |
tree | 9ce41a914064fac2f497d4b0acc43728c4c8f084 /progs/setcap.c | |
parent | cd27cfaf1b6559296e2cbd357079f93f438b1458 (diff) | |
download | libcap2-e6033df7d6f7f913a1807964b770daf7f3567d96.tar.gz |
Add tentitive support for filesystem capabilities with 2.6.23-mm kernels
Diffstat (limited to 'progs/setcap.c')
-rw-r--r-- | progs/setcap.c | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/progs/setcap.c b/progs/setcap.c new file mode 100644 index 0000000..d4a2ee4 --- /dev/null +++ b/progs/setcap.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 1997,2007 Andrew G. Morgan <morgan@kernel.org> + * + * This sets the capabilities of a given file. + */ + +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <sys/capability.h> +#include <unistd.h> + +static void usage(void) +{ + fprintf(stderr, + "usage: setcap [-q] (-|<caps>) <filename> " + "[ ... (-|<capsN>) <filenameN> ]\n" + ); + exit(1); +} + +#define MAXCAP 2048 + +static int read_caps(int quiet, const char *filename, char *buffer) +{ + int i=MAXCAP; + + if (!quiet) { + fprintf(stderr, "Please enter caps for file [empty line to end]:\n"); + } + while (i > 0) { + int j = read(STDIN_FILENO, buffer, i); + + if (j < 0) { + fprintf(stderr, "\n[Error - aborting]\n"); + exit(1); + } + + if (j==0 || buffer[0] == '\n') { + /* we're done */ + break; + } + + /* move on... */ + + i -= j; + buffer += j; + } + + /* <NUL> terminate */ + buffer[0] = '\0'; + + return (i < MAXCAP ? 0:-1); +} + +int main(int argc, char **argv) +{ + char buffer[MAXCAP+1]; + int retval, quiet=0; + cap_t cap_d; + + if (argc < 3) { + usage(); + } + + while (--argc > 0) { + const char *text; + + if (!strcmp(*++argv,"-q")) { + quiet = 1; + continue; + } + if (!strcmp(*argv,"-")) { + retval = read_caps(quiet, *argv, buffer); + if (retval) + usage(); + text = buffer; + } else + text = *argv; + + cap_d = cap_from_text(text); + if (cap_d == NULL) { + perror("fatal error"); + usage(); + } +#ifdef DEBUG + { + ssize_t length; + const char *result; + + result = cap_to_text(cap_d, &length); + fprintf(stderr, "[caps set to:\n%s\n]\n", result); + } +#endif + + if (--argc <= 0) + usage(); + + retval = cap_set_file(*++argv, cap_d); + if (retval != 0) { + fprintf(stderr, + "Failed to set capabilities on file `%s'\n" + " (%s)\n", argv[0], strerror(errno)); + usage(); + } + + cap_free(cap_d); + } + + return 0; +} |