1 /*
2 * Copyright (c) 1997,2007 Andrew G. Morgan <[email protected]>
3 *
4 * This displays the capabilities of a given file.
5 */
6
7 #undef _XOPEN_SOURCE
8 #define _XOPEN_SOURCE 500
9
10 #include <errno.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <stdlib.h>
14 #include <unistd.h>
15 #include <dirent.h>
16 #include <sys/stat.h>
17 #include <sys/types.h>
18 #include <sys/capability.h>
19
20 #include <ftw.h>
21
22 static int verbose = 0;
23 static int recursive = 0;
24 static int namespace = 0;
25
usage(int code)26 static void usage(int code)
27 {
28 fprintf(stderr,
29 "usage: getcap [-h] [-l] [-n] [-r] [-v] <filename> [<filename> ...]\n"
30 "\n"
31 "\tdisplays the capabilities on the queried file(s).\n"
32 );
33 exit(code);
34 }
35
do_getcap(const char * fname,const struct stat * stbuf,int tflag,struct FTW * ftwbuf)36 static int do_getcap(const char *fname, const struct stat *stbuf,
37 int tflag, struct FTW* ftwbuf)
38 {
39 cap_t cap_d;
40 char *result;
41 uid_t rootid;
42
43 if (tflag != FTW_F) {
44 if (verbose) {
45 printf("%s (Not a regular file)\n", fname);
46 }
47 return 0;
48 }
49
50 cap_d = cap_get_file(fname);
51 if (cap_d == NULL) {
52 if (errno != ENODATA && errno != ENOTSUP) {
53 fprintf(stderr, "Failed to get capabilities of file '%s' (%s)\n",
54 fname, strerror(errno));
55 } else if (verbose) {
56 printf("%s\n", fname);
57 }
58 return 0;
59 }
60
61 result = cap_to_text(cap_d, NULL);
62 if (!result) {
63 fprintf(stderr,
64 "Failed to get capabilities of human readable format at '%s' (%s)\n",
65 fname, strerror(errno));
66 cap_free(cap_d);
67 return 0;
68 }
69 rootid = cap_get_nsowner(cap_d);
70 if (namespace && (rootid+1 > 1)) {
71 printf("%s %s [rootid=%d]\n", fname, result, rootid);
72 } else {
73 printf("%s %s\n", fname, result);
74 }
75 cap_free(cap_d);
76 cap_free(result);
77
78 return 0;
79 }
80
main(int argc,char ** argv)81 int main(int argc, char **argv)
82 {
83 int i, c;
84
85 while ((c = getopt(argc, argv, "rvhnl")) > 0) {
86 switch(c) {
87 case 'r':
88 recursive = 1;
89 break;
90 case 'v':
91 verbose = 1;
92 break;
93 case 'n':
94 namespace = 1;
95 break;
96 case 'h':
97 usage(0);
98 case 'l':
99 printf("%s see LICENSE file for details.\n"
100 "Copyright (c) 1997,2007,2021 Andrew G. Morgan"
101 " <[email protected]>\n", argv[0]);
102 exit(0);
103 default:
104 usage(1);
105 }
106 }
107
108 if (!argv[optind])
109 usage(1);
110
111 for (i=optind; argv[i] != NULL; i++) {
112 struct stat stbuf;
113 char *arg = argv[i];
114 if (lstat(arg, &stbuf) != 0) {
115 fprintf(stderr, "%s (%s)\n", arg, strerror(errno));
116 } else if (recursive) {
117 nftw(arg, do_getcap, 20, FTW_PHYS);
118 } else {
119 int tflag = S_ISREG(stbuf.st_mode) ? FTW_F :
120 (S_ISLNK(stbuf.st_mode) ? FTW_SL : FTW_NS);
121 do_getcap(argv[i], &stbuf, tflag, 0);
122 }
123 }
124
125 return 0;
126 }
127