This is probably one of my most irksome things that people mess up all the time. The SUID/GUID bit and the sticky-bit are 2 completely different things.
If you do a man chmod
you can read about the SUID and sticky-bits. The man page is available here as well.
background
excerpt
The letters rwxXst select file mode bits for the affected users: read
(r), write (w), execute (or search for directories) (x), execute/search only
if the file is a directory or already has execute permission for some user
(X), set user or group ID on execution (s), restricted deletion flag or
sticky bit (t).
SUID/GUID
What the above man page is trying to say is that the position that the x bit takes in the rwxrwxrwx for the user octal (1st group of rwx) and the group octal (2nd group of rwx) can take an additional state where the x becomes an s. When this occurs this file when executed (if it's a program and not just a shell script) will run with the permissions of the owner or the group of the file.
So if the file is owned by root and the SUID bit is turned on, the program will run as root. Even if you execute it as a regular user. The same thing applies to the GUID bit.
excerpt
SETUID AND SETGID BITS
chmod clears the set-group-ID bit of a regular file if the file's group ID
does not match the user's effective group ID or one of the user's
supplementary group IDs, unless the user has appropriate privileges.
Additional restrictions may cause the set-user-ID and set-group-ID bits
of MODE or RFILE to be ignored. This behavior depends on the policy
and functionality of the underlying chmod system call. When in doubt,
check the underlying system behavior.
chmod preserves a directory's set-user-ID and set-group-ID bits unless
you explicitly specify otherwise. You can set or clear the bits with
symbolic modes like u+s and g-s, and you can set (but not clear) the bits
with a numeric mode.
SUID/GUID examples
no suid/guid - just the bits rwxr-xr-x are set.
$ ls -lt b.pl
-rwxr-xr-x 1 root root 179 Jan 9 01:01 b.pl
suid & user's executable bit enabled (lowercase s) - the bits rwsr-x-r-x are set.
$ chmod u+s b.pl
$ ls -lt b.pl
-rwsr-xr-x 1 root root 179 Jan 9 01:01 b.pl
suid enabled & executable bit disabled (uppercase S) - the bits rwSr-xr-x are set.
$ chmod u-x b.pl
$ ls -lt b.pl
-rwSr-xr-x 1 root root 179 Jan 9 01:01 b.pl
guid & group's executable bit enabled (lowercase s) - the bits rwxr-sr-x are set.
$ chmod g+s b.pl
$ ls -lt b.pl
-rwxr-sr-x 1 root root 179 Jan 9 01:01 b.pl
guid enabled & executable bit disabled (uppercase S) - the bits rwxr-Sr-x are set.
$ chmod g-x b.pl
$ ls -lt b.pl
-rwxr-Sr-x 1 root root 179 Jan 9 01:01 b.pl
sticky bit
The sticky bit on the other hand is denoted as t
, such as with the /tmp
directory:
$ ls -l /|grep tmp
drwxrwxrwt. 168 root root 28672 Jun 14 08:36 tmp
This bit should have always been called the "restricted deletion bit" given that's what it really connotes. When this mode bit is enabled, it makes a directory such that users can only delete files & directories within it that they are the owners of.
excerpt
RESTRICTED DELETION FLAG OR STICKY BIT
The restricted deletion flag or sticky bit is a single bit, whose
interpretation depends on the file type. For directories, it
prevents unprivileged users from removing or renaming a file in the
directory unless they own the file or the directory; this is called the
restricted deletion flag for the directory, and is commonly found on
world-writable directories like /tmp. For regular files on some
older systems, the bit saves the program's text image on the swap
device so it will load more quickly when run; this is called the sticky bit.
Setting a default owner "automatically" would require a directory setuid
behaving like setgid
. However, while this can be configured on FreeBSD, other UNIX & Linux systems just ignore u+s
. In your case however, there might be another solution.
What I want is to have a directory that can be shared by adding a group to a user. Anything created in this directory inherits the permission scheme from its parent. If there is a better way than what I’m attempting, I’m all ears.
So, basically, from what I see, you want to control the access to a directory using the groups mechanism. However, this does not require you to restrict the permissions in the whole directory structure. Actually, the directory --x
execution bit could be just what you need. Let me give you an example. Assuming that...
- The group controlling the access to the
group_dir
directory is ourgroup
.
- Only people in the
ourgroup
group can access group_dir
.
user1
and user2
belong to ourgroup
.
- The default umask is 0022.
... consider the following setup:
drwxrws--- root:ourgroup |- group_dir/
drwxr-sr-x user1:ourgroup |---- group_dir/user1_submission/
drwxr-sr-x user2:ourgroup |---- group_dir/user2_submission/
-rw-r--r-- user2:ourgroup |-------- group_dir/user2_submission/README
Here, let's assume every item was created by its owner.
Now, in this setup:
- All directories can be browsed freely by everyone in
ourgroup
. Anyone from the group can create, move, delete files anywhere inside group_dir
(but not deeper).
- Anyone who's not in
ourgroup
will be blocked at group_dir
, and will therefore be unable to manipulate anything under it. For instance, user3
(who isn't a member of ourgroup
), cannot read group_dir/user2_submission/README
(even though he has r--
permission on the file itself).
However, there's a little problem in this case: because of the typical umask, items created by users cannot be manipulated by other members of the group. This is where ACLs come in. By setting default permissions, you'll make sure everything's fine despite the umask value:
$ setfacl -dRm u::rwX,g::rwX,o::0 group_dir/
This call sets:
- Default
rw(x)
permissions for the owner.
- Default
rw(x)
permissions for the group.
- No permissions by default for the others. Note that since the others can't access
group_dir
anyway, it does not really matter what their permissions are below it.
Now, if I create an item as user2
:
$ touch group_dir/user2_submission/AUTHORS
$ ls -l group_dir/user2_submission/AUTHORS
rw-rw---- user2:ourgroup group_dir/user2_submission/AUTHORS
With this ACL in place, we can try rebuilding our previous structure:
drwxrws---+ root:ourgroup |- group_dir/
drwxrws---+ user1:ourgroup |---- group_dir/user1_submission/
drwxrws---+ user2:ourgroup |---- group_dir/user2_submission/
-rw-rw----+ user2:ourgroup |-------- group_dir/user2_submission/README
Here again, each item is created by its owner.
Additionally, if you'd like to give a little bit more power/security to those using the directory, you might want to consider a sticky bit. This would, for instance, prevent user1
from deleting user2_submission
(since he has -w-
permission on group_dir
) :
$ chmod +t group_dir/
Now, if user1
tries to remove user2
's directory, he'll get a lovely Operation not permitted
. Note however that while this prevents directory structure modifications in group_dir
, files and directories below it are still accessible:
user1@host $ rm -r user2_submission
Operation not permitted
user1@host $ > user2_submission/README
user1@host $ file user2_submission/README
user2_submission/README: empty (uh-oh)
Another thing to take into account is that the ACLs we used set up default permissions. It is therefore possible for the owner of an item to change the permissions associated to it. For instance, user2
can perfectly run...
$ chown g= user2_submission/ -R
or
$ chgrp nobody user2_submission -R
... hence making his full submission directory unavailable to anyone in the group.
However, since you're originally willing to give full rws
access to anyone in the group, I'm assuming you're trusting these users, and that you wouldn't expect too many malicious operations from them.
Best Answer
The part of the XDG Base Directory specification you cited speaks about setting the sticky bit on files:
The specification is somewhat ambiguous here as file can mean every filesystem entity, non-directory filesystem entity or regular file depending on context. But the sticky bit on directories has a special effect on Linux and is even named different when used on directories in the chmod(1) manpage:
Because of this it's reasonable to assume that file in the XDG documentation in this context means non-directory filesystem entity.
But as the specification is not completely unambiguous it will depend on the implementation of the clean-up mechanism of your distribution. It looks like there is currently no such periodic clean-up at least on Fedora and on Linux Mint, but as this may change in the future and there is no telling how the distributions will interpret this part of the spec, it's safer to set it on every file/socket you want to exclude from periodic cleanups.
EDIT: For
systemd
based distributions,pam_systemd
is responsible for managing $XDG_RUNTIME_DIR. It currently only performs creation on the first login and deletion on the last logout. Alsosystemd
creates sockets in subdirectories of $XDG_RUNTIME_DIR and doesn't set the sticky bit on anything. This strongly suggests that at least nosystemd
based distribution implements periodic clean-up yet.