| 65 | |
| 66 | |
| 67 | int CapabilitiesTestHelper::execute() |
| 68 | { |
| 69 | Try<Capabilities> manager = Capabilities::create(); |
| 70 | if (manager.isError()) { |
| 71 | cerr << "Failed to initialize capabilities manager: " |
| 72 | << manager.error() << endl; |
| 73 | |
| 74 | return EXIT_FAILURE; |
| 75 | } |
| 76 | |
| 77 | if (flags.capabilities.isNone()) { |
| 78 | cerr << "Missing '--capabilities'" << endl; |
| 79 | return EXIT_FAILURE; |
| 80 | } |
| 81 | |
| 82 | if (flags.user.isSome()) { |
| 83 | Try<Nothing> keepCaps = manager->setKeepCaps(); |
| 84 | if (keepCaps.isError()) { |
| 85 | cerr << "Failed to set PR_SET_KEEPCAPS on the process: " |
| 86 | << keepCaps.error() << endl; |
| 87 | |
| 88 | return EXIT_FAILURE; |
| 89 | } |
| 90 | |
| 91 | Try<Nothing> su = os::su(flags.user.get()); |
| 92 | if (su.isError()) { |
| 93 | cerr << "Failed to change user to '" << flags.user.get() << "'" |
| 94 | << ": " << su.error() << endl; |
| 95 | |
| 96 | return EXIT_FAILURE; |
| 97 | } |
| 98 | |
| 99 | // TODO(jieyu): Consider to clear PR_SET_KEEPCAPS. |
| 100 | } |
| 101 | |
| 102 | Try<ProcessCapabilities> capabilities = manager->get(); |
| 103 | if (capabilities.isError()) { |
| 104 | cerr << "Failed to get capabilities for the current process: " |
| 105 | << capabilities.error() << endl; |
| 106 | |
| 107 | return EXIT_FAILURE; |
| 108 | } |
| 109 | |
| 110 | // After 'os::su', 'effective' set is cleared. Since `SETPCAP` is |
| 111 | // required in the `effective` set of a process to change the |
| 112 | // bounding set, we need to restore it first. |
| 113 | if (flags.user.isSome()) { |
| 114 | capabilities->add(capabilities::EFFECTIVE, capabilities::SETPCAP); |
| 115 | |
| 116 | Try<Nothing> set = manager->set(capabilities.get()); |
| 117 | if (set.isError()) { |
| 118 | cerr << "Failed to add SETPCAP to the effective set: " |
| 119 | << set.error() << endl; |
| 120 | |
| 121 | return EXIT_FAILURE; |
| 122 | } |
| 123 | } |
| 124 |
nothing calls this directly
no test coverage detected