Execute with group permission but write with other permission?
I want to allow users of a group to execute a script which then writes out to a file. I want users to run this script to write to the file but not be allowed to write to the file directly.
How might I accomplish this? |
I think you'd have to use suid if this was a binary, causing the program to run as the program user, not as the user.
However, suid is not honoured by the kernel for scripts, due to security issues. Running a script is the same as running the cmds yourself, so I'm not sure you can accomplish what you want. Perhaps if you told us why you think you need this ie what are you trying to achieve. You could try using inotifywait to change the file ownerships upon creation http://linux.die.net/man/1/inotifywait. See here http://www.linuxquestions.org/questi...364/page2.html |
You may be able to use the "setuid" bit on the script to run it as a different user. In other words, a non-privileged user runs the script, but the script file has the "setuid" bit set on its permissions. The owner of the script has permission to write the file. Alternatively you can use "setgid" to run the script as a member of a different group.
Some Linux distos do not allow "setuid" (and possibly not "setgid") for scripts. Here's a link to a good explanation about that. Tuxation - setuid on shell scripts As an example, suppose you give "mygroup" execute permission for a script or program. That means the program's group id must be "mygroup". If the owner of the program is "mygroupadmin" then you also set the "setuid" bit so the program runs as "mygroupadmin" no matter who runs the program. The program creates a file, and sets the file permissions to deny "mygroup" write premission. The file has "mygroupadmin" as the owner with write permission. You have to be careful about other permissions too. If "mygroup" has write access to the directory, then anyone in the group can delete the file. To prevent file deletion you have to deny directory write access to "mygroup". Or, set the "sticky" bit on the directory so that only the owner of the directory or owner of files in the directory can delete files. Since the program is creating and writing a file, you also have to be careful of how symbolic links are handled in the directory. For example, if someone creates a symbolic link having the file name, then the program might write to a completely different file. To avoid that problem, set the "sticky" bit on the directory. Although it is tempting to use "setuid" to run a program as "root" you should avoid doing that. Create a separate user account just for running the program. Give the user account only the minimum required permissions and group membership in order to do what it needs. When a program creates files, the default is to create files owned by that user, and the primary group of that user. Set the user's primary group to the group that you want to own the files it creates. You can add other groups for the user as secondary groups to allow access to files belonging to those other groups. |
I've written a C++ program and given it the user stick bit (chmod u+s). I can confirm that when the group user (505) runs the application their effective userid is the owner (503) by doing this:
Code:
cout << geteuid() << endl However, if I execute the program as 505 (the group user) and have it try to open a file owned by 503 using ofstream, I get a permission denied error. When executed by 503, the program runs and the file opens just fine with ofstream. When using system() in the program to run a shell script which echos $UID it displays "505" instead of the expected "503". Why is it that the program runs as the owner but cannot then write to files or run programs as that user? It reverts back to 505. |
Quote:
|
User 505 does not have permission to run applications owned by 503. I use the u+s sticky bit to allow 505 to execute a program owned by 503 "as" 503 using group permission and the user stick bit.
|
Quote:
|
I tried that. Even though geteuid() returns 503, getuid() still returns 505 despite calling setuid(503) in the actual C++ code. The sticky bit automatically sets the effective user id (geteuid()) but not the actual user id (setuid()). setuid() is supposed to set this but it does not.
Edit: I've found that by calling this: Code:
setreuid(geteuid(), -1) However, I am still unable to write to a file owned by 503. Any other suggestions? |
I was wrong. setreuid() did indeed fix the problem; I had a typo which made it appear as if the problem persisted.
I am using CentOS 6.4. It's possible that for security reasons it requires applications to explicitly set themselves to the real user id rather than the effective user id to take advantage of the sticky bit. The solution in c/c++ is to use setreuid(). Is there alternative to this function for use in bash scripts? |
Consider setting up a process to write the file and using dmesg request the process to write the data. The write message would need to include the pid of the requesting process, and it could do some confirmation processing (sending additional messages as needed) to confirm that the requesting process is one authorized to write to the file.
In this approach, only the daemon would actually need the write permission, not the script or user. (The script could start the daemon with a suid if necessary, but you could start it as a system service during boot, and have it wake up when dmesg needed it.) |
I'm already doing something similar with a poll script and a queue file. The problem is that if I were to allow scripts to write to the queue with group permission then I would have to give the group itself permission to write to the queue; which is a security hole if I want to restrict which users in the group get to send which commands to the queue.
By using the sticky bit on a file which only its owner has permission to write to the queue, I can effectively close this loop. I can then limit which users can access which commands by setting permissions on the sticky-bit file. Only users who can run this file get to write to the queue. |
Probably only "root" can change the user ID, but that should not matter since the effective user ID should be used to determine file access permissions.
I have three other suggestions. There is a "setfsuid( )" function that you can use to set the user ID for file accesses. You should not have to use "setfsuid( )" because "seteuid( )" should have set the file-system user ID. Make sure that the script file does not have the "setuid" bit set. That could change the effective user ID back to 505 when running the script. If you still cannot gain access the the file, make "root" the owner of the program. Then have the program call "setuid(503)" or "seteuid(503)". Using "setuid(503)" is preferred since it permanently reduces privilege. Unfortunately I haven't written any Linux programs so I can't give you any advice from experience. There are quite a few explanations on the Internet of the various functions to set the user ID. |
You could also use sudo to enable the group to run the prog (or even a script) as a completely different user.
The output file would then be unavailable to the group, assuming it (file) has a different group setting as well. |
Quote:
|
He also said
Quote:
|
All times are GMT -5. The time now is 10:41 AM. |