'setcap' overwrites last capability. How do I set multiple capabilities?

I want to give node.js the ability to listen on port 80, and shutdown the computer. Initially I tried these two commands in sequence:

setcap cap_net_bind_service=+ep /usr/bin/nodejs
setcap cap_sys_boot=+ep /usr/bin/nodejs

Then my app was failing to bind to port 80. I checked with getcap:

# getcap /usr/bin/nodejs
/usr/bin/nodejs = cap_sys_boot+ep

If I run setcap again for cap_net_bind_service:

# getcap /usr/bin/nodejs
/usr/bin/nodejs = cap_net_bind_service+ep

I don’t see anything in the man page http://linux.die.net/man/8/setcap about setting multiple capabilities, and try some things in desperation:

# setcap cap_net_bind_service=+ep /usr/bin/nodejs cap_sys_boot=+ep /usr/bin/nodejs
# getcap /usr/bin/nodejs
/usr/bin/nodejs = cap_sys_boot+ep
# setcap cap_net_bind_service=+ep cap_sys_boot=+ep /usr/bin/nodejs
Failed to set capabilities on file `cap_sys_boot=+ep' (No such file or directory)

How do I set multiple capabilities?­­­­­­­

Asked By: Antonius Bloch

||

And one last desperate syntax guess pays off:

# setcap cap_net_bind_service,cap_sys_boot=+ep /usr/bin/nodejs
# getcap /usr/bin/nodejs
/usr/bin/nodejs = cap_net_bind_service,cap_sys_boot+ep
Answered By: Antonius Bloch

For anyone who arrived at this question: if you want to specify different actions for different capabilities, this is the syntax you need:

# this is for illustrative purposes only
# obviously it's not how you would formally define the syntax
setcap "<CAP_0,CAP_1,...><ACTIONS_A> <CAP_2,...><ACTION_B> ..."

So using OP’s example, let’s assume that you want to set =+eip for cap_net_bind_service instead of =+ep, this is what you would do:

setcap "cap_net_bind_service=+eip cap_sys_boot=+ep" /usr/bin/nodejs

More formally, each "capability description" as accepted by setcap is comprised of multiple space-separated "clauses", where each clause is in the form of <CAP_NAME_LIST><OPS><FLAGS> (an <OPS><FLAGS> pair is also referred to as an "action").

So if we take the aforementioned example:

cap_net_bind_service=+eip cap_sys_boot=+ep

Here cap_net_bind_service=+eip is the first clause, where cap_net_bind_service is the comma-separated list of capability names (only one item in this list), =+ are the operators (reset then raise), and eip are the flags (effective, inheritable, and permitted). Similarly cap_sys_boot=+ep is the second clause etc.


If you want a detailed description of the full syntax, you should refer to the manual page of cap_from_text. Here’s a link if you prefer reading from die.net.

Answered By: cyqsimon
Categories: Answers Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.