Introduction
The goal of these exercises is to explore the programmatic functionalities of Linux capabilities and files’ extended attributes.
This work requires a Linux host, which can be virtualized.
Resources required: capabilities.zip
Goal
The purpose is to implement a simple file ownership take-grant
mechanism. Actually, only the super-user of a process with the
CAP_CHOWN
capability can change the ownership of a file.
Furthermore, there is no mechanism to request, or allow, an
ownership modification.
In the Windows NTFS it is possible to indicate, for a given file, that a set of targets can take its ownership. Given that permission, those targets may effectively take its ownership, but on a voluntary basis. The goal is to do something similar in Linux, while not allowing a list of targets (which NTFS supports).
The code to implement this guide is provided in the course Web page.
Software installation
This guide requires the installation of the tools that manipulate files’ extended attributes:
sudo apt install attr
Give ownership}
To give a file ownership to another pair UID / GID, we will develop
a program give
that uses the extended attributes
of a file to express that desire. We will used the attribute
user.new-owner
to provide the UID of the new owner, and the
attribute user.new-group
to provide the GID of the new group owner.
The file give_ownership.c
contains most of the code
necessary to implement a give
application. You
can compile it with the provided Makefile
, using the make
command.
Take ownership
To take a file ownership, to which we previously signaled the
identity of the new UID / GID using the command
give
, we will use a program take
that uses the
previously referred extended attributes of a file to check if we
where granted the right to take its ownership. That can only happen
if the expressed UID equals ours, or the expressed GID equals our
main GID. In all other cases, the ownership is not changed.
The file take_ownership.c
contains most of the code
necessary to implement a take
application. You
can compile it with the provided Makefile
, using the make
command.
The Makefile
already sets the file’s capabilities to add the
CAP_CHOWN
capability the the process’ set of effective
capabilities. This way, the take_ownership
will be able to
change the ownership of a file without running as super-user. You
can check those capabilities with the command: getcap take_ownership
Experimentation
Create two sessions, one for a user (say, user1
), and another for
another user (say, user2
).
With user1
, create a file (say, abc
) in a common directory (say,
/tmp
). With that file, use give
to express your will to
give the file ownership to root (UID 0
, GID 0
). Check the file’s extended attributes with the command getfattr
:
give_ownership 0:0 /tmp/abc
getfattr /tmp/abc
getfattr -n user.new-owner /tmp/abc
getfattr -n user.new-group /tmp/abc
With user2
, try to get the file’s ownership with take
. Check that
it fails, since you are not the target for the ownership transfer.
ls -la /tmp/abc
With user1
again, use give
to express your will to give the file
ownership to user2
UID and GID.
give_ownership user2_uid:user2_gid /tmp/abc
getfattr /tmp/abc
getfattr -n user.new-owner /tmp/abc
getfattr -n user.new-group /tmp/abc
With user2
, try to get the file’s ownership with take
. Check that
it succeeds, since you are now the target for the ownership transfer: ls -la /tmp/abc
.
Observe now the extended attributes of the file manipulated. Check they were gone.
Try this sequence of commands using only only a UID or a GID, or using a UID / GID combination that does not belong to the same user. Check what happens to the file which ownership changes and try to explain what happens from the code of the programs provided.