Assume a user uid=1000 and guids=1000,33,277 is allowed to create a file in the folder /files/. Is there any way I can prevent that the this user allows others to read the file (which are not at least in the groups 1000, 33 or 277)?

Let the file created be /files/user1000.file then the question can be specific:

Is there a way to prevent this outcome of ls /files/user1000.file -al

-rw-rw-r-- 1 1000 1000 6 May 15 17:21 user1000.file

and have this instead:

-rw-rw---- 1 1000 1000 6 May 15 17:21 user1000.file

Maybe using umask? I know that there are things like setgid drw-rws---, so I'm optimistic there might be a way.

Yet I would imagine it is up to the user to decide to do a chmod o+rw user1000.file?


There are two possible solutions to your problem, which both address slightly different scenarios.

The first one would be using umask. The umask is a value which tells the kernel, which access-bits to clear on newly created files (this primarily affects the open(2) and creat(2) system calls — you would still be able to set access bits »forbidden« through the umask value by explicitly calling chmod(2) on the freshly created file). Thus, if you set umask to 0, all access bits requested by the program creating the file are set. If you set it to 04777, all bits are cleared.

Most of the times, the default umask value would be 022, meaning that write permissions are cleared for group and others.

So to solve your problem, you could have the umask value set to 027, which would result in every created file having write access removed for group and all bits cleared for others:

$ umask
$ touch testfile.022
$ ls -l testfile.022
-rw-r--r-- 1 user user 0 May 15 18:56 testfile.022
$ umask 027
$ touch testfile.027
$ ls -l testfile.027
-rw-r----- 1 user user 0 May 15 18:57 testfile.027

To set this in every shell you start, put the appropriate umask call into one of the startup-files of your shell (~/.profile or ~/.bashrc being a good place to start).

Another approach would be using a default Access Control Lists (ACLs) on the directory you want to have those bits cleared in. This approach has two advantages compared to using umask. First, it adds more granularity, namely on directory level, and second, it works for everyone (you won't have to alter the global umask value):

$ umask
$ mkdir acldir
$ cd acldir
$ getfacl .
# file .
# owner: user
# group: user
$ ls -la
total 12
drwxr-xr-x  2 user user    6 May 15 19:11 .
drwxr-xr-x 83 user user 8192 May 15:19:08 ..
$ touch testfile.noacl
$ ls -l testfile.noacl
-rw-r--r-- 1 user user 0 May 15 19:14 testfile.noacl
$ setfacl    -m 'user::rwx,group::r-x,other::---' .
$ setfacl -d -m 'user::rwx,group::r-x,other::---' .
# file: .
# owner: user
# group: user
$ touch testfile.acl
$ ls -l testfile.acl
-rw-r----- 1 user user 0 May 15 19:16 testfile.acl

As you could see, with the default ACL in place, testfile.acl has access bits for others cleared, even with the umask value set to 022.

For a deeper understanding of ACLs, have a look at the acl(5) man page.

Edit: If you want to prevent the file's owner from doing an explicit chown(2) on the file, you would have to bring out the heavy artillery; I think it's not possible in a standards compliant way (in terms of POSIX). There are several security frameworks out there which might allow you to intercept and filter system calls, but which need additional configuration afford. Some of them are:

  • SELinux (hadn't worked with this, yet, but it's fairly generally available; used by RedHat per default, e.g.)
  • RSBAC (heavy configuration afford, but you'll have really fine grained control over what specific users may do and what not)
  • AppArmor (I think Ubuntu uses this)

Yes, you can do so very easily. You just need to set a default umask in your ~/.profile (or in /etc/profile if you want to change it for all users):

umask 0007

With this, new files will be created as you desire:

$ touch user1000.file
$ ls -l user1000.file 
-rw-rw---- 1 terdon terdon 0 May 15 18:56 user1000.file

For more information on umask, you can read the, typically excellent, Arch wiki page on the subject.

  • thank you very much! now I am a little in trouble as I do need different umask settings for different locations (i.e. in /dir1 I would want a different behavior than /dir2 is this also possible? I will of course consult the Arch wiki linked, but I though you might also be able to extend the answer to this aspect, maybe :) – humanityANDpeace May 15 '14 at 17:02
  • @humanityANDpeace as far as I know, that's not possible. You might be able to find some clever hack for it but it's beyond my ken. A dirty hack I can think of is to use bash's PROMPT_COMMAND variable and have it check the current path and set the umask accordingly. I suggest you post a question about this but explain why you need this. There is almost certainly a better way to do this. Just explain what you end objective is and see what people come up with. – terdon May 15 '14 at 17:28
  • @humanityANDpeace heh, I take that back, I think Andreas just showed you how. He might be able to tell you how to make it directory specific. – terdon May 15 '14 at 17:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.