linux-security-module November 2007 archive
Main Archive Page > Month Archives  > linux-security-module archives
linux-security-module: Re: [PATCH] 64 bit capabilities

Re: [PATCH] 64 bit capabilities

From: KaiGai Kohei <kaigai_at_nospam>
Date: Mon Nov 12 2007 - 05:42:22 GMT
To: Andrew Morgan <morgan@kernel.org>


Andrew Morgan,

>> I'll post the patch of setfcaps/getfcap for his tree.
>> I believe it is better way to maintain.
>>
>> Thanks,

The following patch to libcap enables to display file capabilities recursively on the enumerated directories when -r is specified.

In addition, some other features are ported from my getfcap. When an entry contains no file-capabilities, displaying it will be skipped without returning an error. However, -v option enables to display those filenames with no capabilities. -h options displays short usage message.

Please consider to apply it on your tree.

EXAMPLE:
  [kaigai@saba libcap]$ ./progs/getcap -r /tmp   /tmp/ping = cap_net_raw+ep
  [kaigai@saba libcap]$

Thanks, -- OSS Platform Development Division, NEC KaiGai Kohei <kaigai@ak.jp.nec.com> Signed-off-by: KaiGai Kohei <kaigai@ak.jp.nec.com> doc/getcap.8 | 14 +++++++- progs/getcap.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 96 insertions(+), 19 deletions(-) diff --git a/doc/getcap.8 b/doc/getcap.8 index a0e2c41..9ed5c33 100644 --- a/doc/getcap.8 +++ b/doc/getcap.8 @@ -2,14 +2,24 @@ .\" $Id: getcap.8,v 1.1.1.1 1999/04/17 22:16:31 morgan Exp $ .\" written by Andrew Main <zefram@dcs.warwick.ac.uk> .\" -.TH GETCAP 8 "26th April 1997" +.TH GETCAP 8 "12 Nov 2007" .SH NAME getcap \- examine file capabilities .SH SYNOPSIS -\fBgetcap\fP \fIfilename\fP [ ... ] +\fBgetcap\fP [-v] [-r] [-h] \fIfilename\fP [ ... ] .SH DESCRIPTION .B getcap displays the name and capabilities of each specified +.SH OPTIONS +.TP 4 +.B -r +enables recursive search. +.TP 4 +.B -v +enables to display all searched entries, even if it has no file-capabilities. +.TP 4 +.B -h +prints quick usage. .IR filename . One file per line. .SH "SEE ALSO" diff --git a/progs/getcap.c b/progs/getcap.c index 1fbf5d2..a1daa30 100644 --- a/progs/getcap.c +++ b/progs/getcap.c @@ -8,45 +8,112 @@ #include <stdio.h> #include <string.h> #include <stdlib.h> +#include <unistd.h> +#include <dirent.h> +#include <sys/stat.h> +#include <sys/types.h> #include <sys/capability.h> +static int verbose = 0; +static int recursive = 0; + static void usage(void) { fprintf(stderr, - "usage: getcap <filename> [<filename> ...]\n" + "usage: getcap [-v] [-r] [-h] <filename> [<filename> ...]\n" "\n" "\tdisplays the capabilities on the queried file(s).\n" ); exit(1); } -int main(int argc, char **argv) +static void do_recursive(const char *fname); + +static void do_getcap(const char *fname) { - char *result=NULL; + cap_t cap_d; + char *result; - if (argc < 2) { - usage(); + cap_d = cap_get_file(fname); + if (cap_d == NULL) { + if (errno != ENODATA) { + fprintf(stderr, "Failed to get capabilities of file `%s' (%s)\n", + fname, strerror(errno)); + } else if (verbose) { + printf("%s\n", fname); + } + goto out; } - for ( ++argv; --argc > 0; ++argv ) { - ssize_t length; - cap_t cap_d; + result = cap_to_text(cap_d, NULL); + if (!result) { + fprintf(stderr, + "Failed to get capabilities of human readable format at `%s' (%s)\n", + fname, strerror(errno)); + cap_free(cap_d); + return; + } + printf("%s %s\n", fname, result); + cap_free(cap_d); + cap_free(result); - cap_d = cap_get_file(argv[0]); + out: + if (recursive) { + struct stat stbuf; - if (cap_d == NULL) { - fprintf(stderr, "Failed to get capabilities for file `%s' (%s)\n", - argv[0], strerror(errno)); - continue; + if (stat(fname, &stbuf)) { + fprintf(stderr, "Failed to get attribute of file `%s' (%s)\n", + fname, strerror(errno)); + } else if (S_ISDIR(stbuf.st_mode)) { + do_recursive(fname); } + } +} + +static void do_recursive(const char *fname) +{ + DIR *dirp; + struct dirent *dent; + char buffer[PATH_MAX]; - result = cap_to_text(cap_d, &length); + dirp = opendir(fname); + if (dirp == NULL) { + fprintf(stderr, "Failed to open directory `%s' (%s)\n", + fname, strerror(errno)); + return; + } - printf("%s: %s\n", *argv, result); + while ((dent = readdir(dirp)) != NULL) { + if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..")) + continue; + snprintf(buffer, PATH_MAX, "%s/%s", fname, dent->d_name); + do_getcap(buffer); + } + closedir(dirp); +} - cap_free(result); - cap_free(cap_d); +int main(int argc, char **argv) +{ + int i, c; + + while ((c = getopt(argc, argv, "rvh")) > 0) { + switch(c) { + case 'r': + recursive = 1; + break; + case 'v': + verbose = 1; + break; + default: + usage(); + } } + if (!argv[optind]) + usage(); + + for (i=optind; argv[i] != NULL; i++) + do_getcap(argv[i]); + return 0; } - To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html