Make all new files in a directory accessible to a group
If at all possible, use access control lists (ACL).
Under Linux, make sure that the filesystem you're using supports ACLs (most unix filesystems do). You may need to change the mount options to enable ACLs: with ext2/ext3/ext4, you need to specify the acl
mount option explicitly, so the entry in /etc/fstab
should look like /dev/sda1 / ext4 errors=remount-ro,acl 0 1
. Run mount -o remount,acl /
to activate ACLs without rebooting. Also install the ACL command line tools getfacl
and setfacl
, typically provided in a package called acl
.
Now that the one-time setup is over, change the directory's ACL to give the group write permissions and to make these permissions inherited by newly created files. Under Linux:
setfacl -d -m group:GROUPNAME:rwx /path/to/directory
setfacl -m group:GROUPNAME:rwx /path/to/directory
If ACLs are not an option, make the directory owned by the group GROUPNAME
, and set its permissions to 2775 or 2770: chmod g+rwxs /path/to/directory
. The s
here means the setgid bit; for a directory, it means that files created in this directory will belong to the group that owns the directory.
You'll also need to set Alice and Bob's umask to make all their files group-writable by default. The default umask on most systems is 022, meaning that files can have all permissions except write by group and other. Change that to 002, meaning to forbid only write-by-other permission. You would typically put that setting in your ~/.profile
:
umask 002 # or 007 to have files not readable by others
You can control the assigned permission bits with umask
, and the group by making the directory setgid to GROUPNAME
.
$ umask 002 # allow group write; everyone must do this
$ chgrp GROUPNAME . # set directory group to GROUPNAME
$ chmod g+s . # files created in directory will be in group GROUPNAME
Note that you have to do the chgrp
/chmod
for every subdirectory; it doesn't propagate automatically (that is, neither existing nor subsequently created directories under a setgid directory will be setgid, although the latter will be in group GROUPNAME
).
Also note that umask
is a process attribute and applies to all files created by that process and its children (which inherit the umask
in effect in their parent at fork()
time). Users may need to set this in ~/.profile
, and may need to watch out for things unrelated to your directory that need different permissions. modules may be useful if you need different settings when doing different things.
You can control things a bit better if you can use POSIX ACLs; it should be possible to specify both a permissions mask and a group, and have them propagate sensibly. Support for POSIX ACLs is somewhat variable, though.
This question is a good fit for linux acl
. Since you don't state your OS, I'll assume Linux in what follows. Here is an example session.
I don't know of a really good acl
tutorial, but you could do worse than http://www.vanemery.com/Linux/ACL/linux-acl.html
Note that the default acl
behaves like a local umask. Since at least in Linux, umasks are applied globally, this is the only way I know to get the effect of a local umask. For some reason this a little known feature. The net is littered with people asking about a local umask override, but almost nobody seems to think of using acl
.
Also note that you need to mount the partition you are working in with acl
support, eg.
/dev/mapper/debian-acl /mnt/acl ext3 defaults,acl 0 2
Session follows:
/mnt/acl$ mkdir foo
/mnt/acl$ getfacl foo
# file: foo
# owner: faheem
# group: faheem
user::rwx
group::r-x
other::r-x
Set the group of foo
to be staff
, and set the acl of group and user of foo
to rwx
.
/mnt/acl$ chgrp staff foo
/mnt/acl$ setfacl -R -m u::rwx,g::rwx foo
/mnt/acl$ getfacl foo
# file: foo
# owner: faheem
# group: staff
user::rwx
group::rwx
other::r-x
Set default acls of user and group to rwx
as well. This defines permissions that files and directories inherit from foo
. So all files and directories created under foo will have group permissions rw
.
/mnt/acl$ setfacl -d --set u::rwx,g::rwx,o::- foo
/mnt/acl$ getfacl foo
# file: foo
# owner: faheem
# group: staff
user::rwx
group::rwx
other::r-x
default:user::rwx
default:group::rwx
default:other::---
Now create some files in foo
as users faheem
and john
.
/mnt/acl$ cd foo
/mnt/acl/foo$ touch bar
# switch to user john for this next command.
/mnt/acl/foo$ touch baz
List files. Notice that both files owned by faheem
and files owned by john
are created with group permissions rw
.
/mnt/acl/foo$ ls -la
total 3
drwxrwxr-x+ 2 faheem staff 1024 May 9 01:22 .
drwxr-xr-x 4 faheem faheem 1024 May 9 01:20 ..
-rw-rw---- 1 faheem faheem 0 May 9 01:20 bar
-rw-rw---- 1 john john 0 May 9 01:22 baz