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:
  [EMAIL PROTECTED] libcap]$ ./progs/getcap -r /tmp
  /tmp/ping = cap_net_raw+ep
  [EMAIL PROTECTED] libcap]$

Thanks,
-- 
OSS Platform Development Division, NEC
KaiGai Kohei <[EMAIL PROTECTED]>

Signed-off-by: KaiGai Kohei <[EMAIL PROTECTED]>

 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 <[EMAIL PROTECTED]>
 .\"
-.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 [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to