1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
/*
* Copyright (c) 1997-8,2007-8,19,21-22 Andrew G. Morgan <morgan@kernel.org>
*
* This displays the capabilities of given target process(es).
*/
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/capability.h>
static void usage(int code)
{
fprintf(stderr,
"usage: getpcaps [opts] <pid> [<pid> ...]\n\n"
" This program displays the capabilities on the queried process(es).\n"
" The capabilities are displayed in the cap_from_text(3) format.\n"
"\n"
" Optional arguments:\n"
" --help, -h or --usage display this message.\n"
" --verbose use a more verbose output format.\n"
" --ugly or --legacy use the archaic legacy output format.\n"
" --iab show IAB of process too.\n"
" --license display license info\n");
exit(code);
}
int main(int argc, char **argv)
{
int retval = 0;
int verbose = 0;
int iab = 0;
cap_iab_t noiab = cap_iab_init();
if (argc < 2) {
usage(1);
}
for (++argv; --argc > 0; ++argv) {
long lpid;
int pid;
char *endarg;
cap_t cap_d;
const char *arg = *argv;
if (!strcmp(arg, "--help") || !strcmp(arg, "--usage") ||
!strcmp(arg, "-h")) {
usage(0);
} else if (!strcmp(arg, "--license")) {
printf("%s see LICENSE file for details.\n"
"[Copyright (c) 1997-8,2007-8,19,21-22"
" Andrew G. Morgan <morgan@kernel.org>]\n",
arg);
exit(0);
} else if (!strcmp(arg, "--verbose")) {
verbose = 1;
continue;
} else if (!strcmp(arg, "--ugly") || !strcmp(arg, "--legacy")) {
verbose = 2;
continue;
} else if (!strcmp(arg, "--iab")) {
iab = 1;
continue;
}
errno = 0;
lpid = strtol(arg, &endarg, 10);
if (errno == 0) {
if (*endarg != '\0') {
errno = EINVAL;
} else if (lpid < 0 || lpid != (pid_t) lpid) {
errno = EOVERFLOW;
}
}
if (errno != 0) {
fprintf(stderr, "Cannot parse pid %s: (%s)\n", arg, strerror(errno));
retval = 1;
continue;
}
pid = lpid;
cap_d = cap_get_pid(pid);
if (cap_d == NULL) {
fprintf(stderr, "Failed to get cap's for process %d:"
" (%s)\n", pid, strerror(errno));
retval = 1;
continue;
}
char *result = cap_to_text(cap_d, NULL);
if (iab) {
printf("%s:", arg);
if (verbose || strcmp("=", result) != 0) {
printf(" \"%s\"", result);
}
cap_iab_t iab_val = cap_iab_get_pid(pid);
if (iab_val == NULL) {
fprintf(stderr, " no IAB value for %d\n", pid);
exit(1);
}
int cf = cap_iab_compare(noiab, iab_val);
if (verbose ||
CAP_IAB_DIFFERS(cf, CAP_IAB_AMB) ||
CAP_IAB_DIFFERS(cf, CAP_IAB_BOUND)) {
char *iab_text = cap_iab_to_text(iab_val);
if (iab_text == NULL) {
perror(" no text for IAB");
exit(1);
}
printf(" [%s]", iab_text);
cap_free(iab_text);
}
cap_free(iab_val);
printf("\n");
} else if (verbose == 1) {
printf("Capabilities for '%s': %s\n", arg, result);
} else if (verbose == 2) {
fprintf(stderr, "Capabilities for `%s': %s\n", arg, result);
} else {
printf("%s: %s\n", arg, result);
}
cap_free(result);
result = NULL;
cap_free(cap_d);
}
return retval;
}
|