create only file permission on linux
Not sure if this can be done, but if it can it probably involves ACLs, not traditional Unix permission modes.
Take a look at the SELinux kernel extension. It is standard and well supported by the major distributions. It allows very fine grained permission control, up to complete paranoida.
This doesn’t really belong here, though you will definitely find people who can answer the question 🙂 Try Super User or unix.StackExchange.com.
2 Answers 2
I would try to change file permissions after creation using inotifywait. This (untested) snippet might help a bit, but is definitely not very elegant. It sets root as the owner of all created files in /path/to/dir and removes write-permission for group and others.
while true; \ do inotifywait -e create /path/to/dir/ && \ chown root /path/to/dir/* && \ chmod g-wo-w /path/to/dir/*; \ done
Hope that helped a bit *jost
If it is also ok that the user that created the file can change them, you can use the sticky bit. This is the first digit if you give chmod a 4 digit argument.
su - mkdir stickydir chmod 1775 stickydir chown user.group stickydir
Now all members of group can write to the dir, but only the user that created a file or root can change the files
su - user1 #member of group touch stickydir/stickytest-user1 #ok su - user2 #member of group touch stickydir/stickytest-user2 #ok rm stickydir/stickytest-user1 #permission denied rm stickydir/stickytest-user2 #ok
Can files be created with permissions set on the command line?
When creating directories, mkdir -m
open("file", O_WRONLY | O_APPEND | O_CREAT, 0777);
Is using touch followed by a chmod my only option here? Edit: After trying out teppic’s suggestion to use install , I ran it through strace to see how close to atomic it was. The answer is, not very:
$ strace install -m 777 /dev/null newfile . open("newfile", O_WRONLY|O_CREAT|O_EXCL, 0666) = 4 fstat(4, ) = 0 . fchmod(4, 0600) = 0 close(4) = 0 . chmod("newfile", 0777) = 0 .
6 Answers 6
You could use the install command with a dummy file, e.g.
install -b -m 755 /dev/null newfile
The -b option backs up newfile if it already exists. You can use this command to set the owner as well.
On Linux it’s usually part of GNU coreutils or BusyBox, but it’s also available on systems derived from 4.2BSD, e.g. FreeBSD, NetBSD or OpenBSD.
It’s a useful little command. As its name suggests it’s really designed for installing software compiled from source code, to save having to use chmod, chown, and so forth all the time.
Note that mode 755 is the default permissions of files created with install , so -m 755 is not needed.
@Kusalananda It’s obviously just an example of how to set a mode, since that was the question, not how to set 755.
install does not atomically create files with the given permissions. It calls fchmod() separately. An unauthorised user may open the file between the creation and the permissions change, thus it possible to read contents later that they are not allowed to read (e.g. for a private key file). Thus install should not be used if file permission security is important. (This was edited into the question, but I think it’s good to state it under this answer since it’s currently marked accepted despite not fulfilling the requested «atomic» requirement.)
touch always creates the file if it doesn’t exist, always follows symbolic links, and always makes the file non-executable. You can decide the read and write bits through the umask.
(umask 077; touch file) # creates a 600 (rw-------) file (umask 002; touch file) # creates a 664 (rw-rw-r--) file
“Safe” atomic file creation (in particular, with O_NOFOLLOW ) is not possible with traditional shell tools. You can use sysopen in perl. If you have the BSD-inspired mktemp utility, it creates a file atomically with O_NOFOLLOW ; you’ll have to to call chmod afterwards if the default mode of 600 is not the right one.
I was in the process of writing out a more detailed explanation, but the wikipedia articles covers everything just fine.
If only touch had the option of creating executable files, that’s really what I’m after. Then umask could be used to tailor the details. Sadly there is no way with umask and touch to create executables.
@quornian You can’t create a non-empty file atomically anyway. What’s the point of creating an empty executable file atomically? Use touch followed by chmod +x .
You can create non-empty, executables files atomically with. ln or mv. You can always create the file with the right content and permissions in a directory created with umask 077 and move it or ln it afterwards.
Building on @teppic’s answer, if you want to create the file with content and mode at the same time (bash):
With zsh’s sysopen builtin (enabled with zmodload zsh/system ) you can specify the mode with -m , still subject to umask , but you can set it to 0:
zmodload zsh/system (umask 0 && sysopen -u fd -m 777 -o excl file)
Should be atomic. strace shows:
openat(AT_FDCWD, "file", O_RDONLY|O_CREAT|O_EXCL|O_NOCTTY, 0777) = 3
-o excl is for it to fail with a *»file exists»» error when the file already existed, so you can do (. ) || chmod 777 file for instance. Replace with -o creat to just open it (still in read-only with -r ) when it already existed. In any case, the fd is closed as soon as the subshell exists.
You can also set the uid and gid at the same time atomically if you’re superuser and set the EGID and EUID variables (in that order) beforehand:
(umask 0 && EGID=456 EUID=123 && sysopen -u fd -m 777 -o excl file)
I have a bash script in my home directory /home/anthony/touchmod.sh containing:
#!/bin/bash touch "$2" chmod "$1" "$2"
So if I need to create readme.txt with 644 permissions I can type:
I don’t think you can really do this from just standard tools, but if you have access to a python interpreter, you can do something like:
python3 -c 'import os, sys, shutil; shutil.copyfileobj(sys.stdin, open("filename.txt", "w", opener=lambda name, flag: os.open(name, flag, mode=0o631)))'
Expanded, the python script basically does:
import os, sys, shutil file_opener = lambda name, flag: os.open(name, flag, mode=0o631) dest = open("filename.txt", "w", opener=file_opener) shutil.copyfileobj(sys.stdin, dest)
There's probably something similar in other scripting language interpreter's toolkit.
$ strace python3 -c 'import os, sys, shutil; shutil.copyfileobj(sys.stdin, open("filename.txt", "w", opener=lambda name, flag: os.open(name, flag, mode=0o631)))' , AT_EMPTY_PATH) = 0 ioctl(3, TCGETS, 0x7ffe4fce65e0) = -1 ENOTTY (Inappropriate ioctl for device) lseek(3, 0, SEEK_CUR) = 0 ioctl(3, TCGETS, 0x7ffe4fce6430) = -1 ENOTTY (Inappropriate ioctl for device) lseek(3, 0, SEEK_CUR) = 0 brk(0x55c88d356000) = 0x55c88d356000 read(0, "file_content\n", 65536) = 13 brk(0x55c88d346000) = 0x55c88d346000 read(0, "", 65523) = 0 read(0, "", 65536) = 0 write(3, "file_content\n", 13) = 13 .
Alternatively, if the only reason you care about atomicity is just to prevent the file content being read from a hostile process running as other users, and not necessarily the use of atomicity of open(. mode) itself, you can just set the umask to 777 in a subprocess so that the file is first created to deny permission to everyone:
$ (umask 777; filename.txt) $ ls -lah filename.txt ---------- 1 lieryan lieryan 13 Sep 8 15:58 filename.txt
then set the file permission with the right value right afterwards:
Or, putting it all together:
$ (umask 777; filename.txt; chmod 631 filename.txt)
This is still susceptible to race condition attacks from other processes running as the same user, but if you have to worry about that, you're probably worrying about the wrong thing.
What are permissions to create a folder or file?
I've seen lots of stuff on the internet about HOW to set permissions. Please tell me WHAT permissions are required for a user to be able to create a folder or a file. I would have thought just w but I'm not sure.
The only permissions are read, write, and execute. What is the actual problem that you are trying to solve? It's better to ask about the actual problem and provide details and context than ask a coded/vague question that won't actually help you solve the problem.
small addition: the directory -above- where you want to make a dir or file needs to be rwx for your user and/or your group and/or others depending on the user used to create it.
2 Answers 2
To change file and directory permissions change directories with cd to the directory that contains the file/directory whose permissions you want to change, and use the command chmod (change mode).
Add write permissions to a file or a directory:
chmod +w filename chmod +w directoryname
If you want to read the file and also want write permissions, you need read permissions too. Add read/write permissions to a file or a directory:
chmod +rw filename chmod +rw directoryname
In Linux (and all Unix-like operating systems), there's the principle that "everything is a file". That includes, among other things, directories. A directory is basically a file that contains information about the contents of the directory.
So if you have, for example, the directory /home/kristy/some_files/ and want to create a new file (or a new subfolder) in this directory, you need to write to the file representing this directory. And in order to do that, you need write permissions on this directory.
Thanks for your responses. Apparently I was right: the user needs w. The permissions on my folder are: drw-rw-rw- 2 www-data www-data 4096 Dec 20 20:05 tmp Yet when I try to write a file to it from a php called shell_exec command I get this: [Errno 13] Permission denied: '/var/www/tmp/TestTopics.txt' How can I make the www-data user able to write a file to /var/www/tmp ?
Sorry, this forum is very restrictive. The permissions on the folder: /var/www/tmp are drw-rw-rw- 2 www-data www-data 4096 Dec 20 20:05 tmp I'm trying to create/write a file to the tmp folder in Python from a php shell_exec command. I'm getting this error in Python: [Errno 13] Permission denied: '/var/www/tmp/TestTopics.txt' How can I make the www-data user able to create a file in /var/www/tmp ?
@kristy1024 This isn't a forum, I'm afraid. You may want to look at the tour to find out how this site is intended to be used. Regarding your (new) question, write permission on the directory should allow any user that has this permission to create a new file in the directory. If the file already exists, you need to look at the file's permissions. Also check that your programs or scripts actually are running as www-data , that's not necessarily the case. The details may depend on how exactly you have set up your system.
Create file in folder: permission denied
I have a problem copying files to a directory on Ubuntu 12.04. I create a directory in the home directory so that the path where I want to copy to is:
francisco-vergara@Francisco-Vergara:/home/sixven/camp_sms/inputs$ touch test_file.txt touch: can not make `touch' on «test_file.txt»: permission denied
I can not copy files directly in that directory. How can I assign permissions with the chown & chmod commands to copy the files? I do not know which user and group to use.
From what you have copy-pasted, you are running touch as user francisco-vergara , but your directory is in /home/sixven is that really the home of user francisco-vergera or does it belong to a sixven user ? You should clarify what you want to do exactly. Write in another user's home ? Share that directory among a group ?
3 Answers 3
First of all you have to know that the default permission of directories in Ubuntu is 644 which means you can't create a file in a directory you are not the owner.
you are trying as user:francisco-vergara to create a file in a directory /home/sixven/camp_sms/inputs which is owned by user:sixven .
So how to solve this:
- You can either change the permission of the directory and enable others to create files inside.
sudo chmod -R 777 /home/sixven/camp_sms/inputs
sudo chown -R francisco-vergara:francisco-vergara /home/sixven/camp_sms/inputs
So i advise you to use Option 1.
Or if this directory will be accessed by both users you can do the following trick:
change ownership of the directory to user:francisco-vergara and keep the group owner group:sixven .
sudo chown -R francisco-vergara /home/sixven/camp_sms/inputs
Like that both users can still use the directory.
But as I said you before It's easiest and more efficient to use option 1.