Program (or code?) to create empty file with specified permissions
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Program (or code?) to create empty file with specified permissions
Is there a standard program in Linux that you can use to create an empty file with a specified set of permission bits? For example, when you use the "mkdir" command you can pass in "-m 0750" to create a directory with the permission bits 0750 already set. Though, in my case I want to create regular files, not directories or special files. I looked through TOUCH(1), but there doesn't seem to be a "mode" or "permissions" switch.
Just to be clear, a few points:
- The program must open the file with the specified permissions, not open them with one set of permissions and change them to another.
- Yes, I know how to write a C or Ruby program that could do this... but I'd rather use one that is already written/installed if available.
- No, adjusting the umask each time I want to create such a file is not a good option for me.
Wow, three posts for ignoring each of my three points. Alright already, I'll write my own program. I just thought that, since there was a "mkdir" program and a "mknod" program that allow passing in a mode-line, there might also be some kind of "mkregularfile" program that does the same thing.
Well, like they always say... if you want it done right, you've gotta code it yourself.
Well there's 'install /dev/null -m mode -o owner -g group /path/to/file' which comes as close to a complete shell one-liner I can think of but it chmods after open so no dice. Moved: This thread is more suitable elsewhere and has been moved accordingly to help your thread/question get the exposure it deserves.
Well, this is interesting... even the open function from fcntl.h in C doesn't seem to do quite what I want. From OPEN(2):
Code:
int open(const char *pathname, int flags, mode_t mode);
[...]
mode specifies the permissions to use in case a new file is created. This argument must be supplied when O_CREAT
is specified in flags; if O_CREAT is not specified, then mode is ignored. The effective permissions are modified
by the process's umask in the usual way: The permissions of the created file are (mode & ~umask). Note that this
mode only applies to future accesses of the newly created file; the open() call that creates a read-only file may
well return a read/write file descriptor.
So, the permission bits I pass in are still going to modified against umask. Hmm. You'd think there'd be some low-level function that could just ignore the umask in creating the file.
Or does that violate some law of how the OS works? I could call umask(0) before calling open(), but is that strictly necessary? I know Ruby, at least, has a function that lets you create the file with whatever bit permissions you want... but I haven't read the source code yet so I don't know what is actually going on behind the scenes in a Linux implementation.
Oops... correction on that last point: apparently Ruby's File.new method also modifies the desired permissions with the umask. At least, on my system (amd64 Gentoo) with ruby 1.8.7.
Moved: This thread is perhaps more suitable in Programming and has been moved accordingly to help your thread/question get the exposure it deserves. If this turns out to not be the best place for the thread, OP may feel welcome to report it again, and suggest another location, and we'll certainly consider it.
Is there a standard program in Linux that you can use to create an empty file with a specified set of permission bits?
but then specify
Quote:
The program must open the file with the specified permissions, not open them with one set of permissions and change them to another.
So ,which is it? Do you just want to create the file or open it? If it's "open," in what context do you mean "open?"
If it's just "create," then the two-step process (touch followed by chmod) can easily be placed in an executable script in a directory in your $PATH and used as a command.
You could grab the source code for the touch command and modify it to suit your needs. (I think touch is part of the GNU bin-utilities package, but I haven't checked that supposition.)
The bit about the umask: I believe the mask is set by the directory in which you're creating the file together with your process permissions. So, overriding that would create a rather worrisome security hole in your system. Not, I hope, something you really want to accomplish.
Note that open(2) with O_CREAT|O_EXCL is not atomic on NFS on Linux prior to 2.6.5.
link(2) is atomic, so the standard answer is a create-link-check dance, similar to this or this.
If you want to roll your own solution in C (use unistd.h and not stdio.h), you can follow this secure recipe:
Set a new umask using umask(2).
The umask is private to this process, and does not affect any other processes (unless forked or executed by this process).
Create a temporary subdirectory using mkdir(2), which is atomic.
The subdirectory should be in the target directory; it must be on the same filesystem.
Pick a random name for the subdirectory, and retry at least a few times if the mkdir(2) fails.
Use mode 0300 (d-wx------) for the subdirectory.
Create the file using open(2) and O_CREAT|O_EXCL in that subdirectory.
Use a random name to guard against race exploit attempts.
Verify using fstat(2) that the link count of the created file is 1.
If not, unlink(2) the file, rmdir(2) the subdirectory, and fail.
Use link(2) to create a hardlink to the created file, from the actual target file and directory.
If it fails, unlink(2) both files, rmdir(2) the subdirectory, and fail.
Note that link(2) will always fail if the two are on different filesystems.
Verify using lstat(2) and fstat(2) that both are the same, and have link count 2.
unlink(2) the file in the subdirectory. If this fails, unlink(2) the other file too, rmdir(2) the directory, and fail.
rmdir(2) the subdirectory. Again, if this fails, unlink(2) the other file too, rmdir(2) the directory, and fail.
If you're really careful, you can do another lstat(2) to check the file stats have not changed, other than link count back to 1.
Done.
This way the temporary subdirectory guarantees atomicity and also guards against hardlink race exploits. It is a bit resource intensive, but it is very safe against race exploits. And if it succeeds, the file is guaranteed to have been atomically created. It will never accidentally delete an existing file, guaranteed by link(2).
There has been a lot of discussion on how to safely create secure temporary files, in many libraries (coreutils, glibc) and scripting languages. Most of these have serious limitations -- for example, the umask dependability, and non-atomicity on NFS or other filesystems -- which are well known to developers, but not to users.
Hope this helps,
Nominal Animal
Last edited by Nominal Animal; 03-21-2011 at 01:46 AM.
@GrapefruiTgirl: Moving it to programming was fine. Changing the title... not so much. But both titles probably aren't specific enough, anyway, so no hard feelings.
@frieza, et al: Maybe a little background would help: I'm really trying to figure out some of the deeper aspects of how Linux ACLs work. I am hesitant to dive into a /new/ discussion, except to say that is has to do with understanding how to make good use of default ACLs. From ACL(5):
Code:
OBJECT CREATION AND DEFAULT ACLs
The access ACL of a file object is initialized when the object is created with any of the creat(), mkdir(), mknod(),
mkfifo(), or open() functions. If a default ACL is associated with a directory, the mode parameter to the functions creat-
ing file objects and the default ACL of the directory are used to determine the ACL of the new object:
1. The new object inherits the default ACL of the containing directory as its access ACL.
2. The access ACL entries corresponding to the file permission bits are modified so that they contain no permissions that
are not contained in the permissions specified by the mode parameter.
Again, hesitant to get into a new discussion, but in any case: one method of practical experimentation was to create files (of various permissions) and see how they were affected by the default ACL entries of the parent directory. So I thought: "Well, I wonder if there is a handy Linux utility (there must be!) that allows you to pass in an octal mode string, and then create an empty file with those permissions."
Of course, anyone can create a script that creates and empty file, and then chmod's the permissions to something else. But then that leaves the lingering question: Are the default ACL entries affecting the permissions of the file at the point when the file was /actually/ created, or after the file permissions were changed by chmod? Hence the seemingly overzealous concern about when the file receives the desired permissions.
@PTrenholme: Because of my practical background, I tend to think of creating and opening a file as the same thing, though technically they are different, depending on what sense you apply to the word "opening"
@Nominal Animal: Thanks for a very thorough answer, though I think (if I am even following it correctly) you are trying to help me solve a problem different from the one I am actually concerned with.
Of course, anyone can create a script that creates and empty file, and then chmod's the permissions to something else. But then that leaves the lingering question: Are the default ACL entries affecting the permissions of the file at the point when the file was /actually/ created, or after the file permissions were changed by chmod?
At the point when the file was actually created. They are applied by the kernel.
I assumed you were aware and worried about the security problem between the two operations. It is a serious risk; there are many known attack methods that exploit this interval where the file has the default access mode (which is only "tightened" afterwards). Several local privilege escalation vulnerabilities have been based exactly on this; but still most developers don't seem to take it seriously.
To avoid those problems, you need to follow a recipe such as I outlined. While there are command-line utilities and library functions (in practically every language) to help combat that problem for temporary files, almost all have severe limitations (due to the resource usage of a "really secure" method) -- but nothing for general file creation, as far as I know.
Nominal Animal
Last edited by Nominal Animal; 03-21-2011 at 01:44 AM.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.