summaryrefslogtreecommitdiff
path: root/progs/setcap.c
diff options
context:
space:
mode:
authorAndrew Morgan <morgan@kernel.org>2007-07-18 00:02:08 -0700
committerAndrew Morgan <morgan@kernel.org>2007-08-13 23:33:12 -0700
commite6033df7d6f7f913a1807964b770daf7f3567d96 (patch)
tree9ce41a914064fac2f497d4b0acc43728c4c8f084 /progs/setcap.c
parentcd27cfaf1b6559296e2cbd357079f93f438b1458 (diff)
downloadlibcap2-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.c112
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;
+}