Well, Linux capability flags describe what a thread or a process is allowed to do. Each flag is pretty well described in man 7 capabilities
The basic principles are pretty simple:
- Capabilities are reset whenever a new binary is exec'd.
Capabilities do not change when a new process is forked or a new thread is started.
- When a process/thread acquires privileges (changes to root successfully), it gets all capabilities.
- When a process/thread drops privileges (changes to a non-root user and group), it drops all capabilities.
(This happens when a real, effective, or filesystem user or group ID changes from zero to non-zero, with all others either set or being set non-zero. In other words, when the "last trace" of superuser privileges is dropped.)
A process can set the PR_SET_KEEPCAPS control using prctl() to keep capabilities when dropping privileges. It does not affect exec'ing a binary, though, and the control is always unset at exec.
The exact definition of reset
(i.e. what happens to capabilities at exec time) is described in the capabilities man page. The rules may be confusing, so only worry about the rules if the typical use case below does not fit your needs.
The main thing to note is that by default, reset
means all capabilities are dropped for unprivileged users, i.e. everybody except root; and that you can give unprivileged users exec'ing some binary extra capabilities by adding them to the permitted and effective sets for that binary.
So, the typical use case -- when run as an unprivileged user (non-root), allow the program to do these
additional things -- is simple. Just add the desired capability flags to both the effective and permitted sets for that binary, by running either
setcap cap_something=pe binary-file
or, if you want to set multiple capabilities,
setcap "cap_first=pe cap_second=pe cap_third=pe" binary-file
You'll obviously need superuser privileges, so run the command as root or via sudo. Afterwards, whenever that binary-file
is exec'd by an unprivileged user, it will have those capabilities and those capabilities only. (If it is exec'd by superuser/root, it will of course have all capabilities.)
This does not work for symbolic links or scripts, however; it only works for actual program binaries. I recommend using first which program
to locate the program file, then file /path/to/program
to trace the symlink chain and detect possible scripts. You may need to read the scripts to find out where the actual program binary is located.
Note that when upgrading a package, the package manager may replace a binary with a new file. This means that the capability flags are lost. I am not sure which package managers, if any, retain the capability flags. They are rarely used, after all.
You can limit the groups that can a binary with extra capabilities, by copying the binary to a new directory, limiting access to that directory to the desired group only, and then setting the file capabilities as above. This also means you don't need to worry about updates breaking the file capabilities. (If you want to limit access to a specific user
, you'd better use POSIX ACLs, with the directory owned by root, and grant access to the user via an ACL. If you let the user own the directory, the user can always replace the binary with something else.)
Hope this helps,