LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - General (https://www.linuxquestions.org/questions/linux-general-1/)
-   -   Allow users to chmod certain directories via sudoers file (https://www.linuxquestions.org/questions/linux-general-1/allow-users-to-chmod-certain-directories-via-sudoers-file-4175450949/)

johnmccarthy 02-20-2013 08:01 AM

Allow users to chmod certain directories via sudoers file
 
Can anyone provide an example of what I should type in the sudoers file so a specific user (example: smith) can perform a chmod on files located in /data/security/ only?

It seems when I enter smith ALL=NOPASSWD:/bin/chmod 755 /data/security/* smith can perform a chmod on any files, regardless of the directory.

A million thanks,
Johnny Mac

linosaurusroot 02-20-2013 08:28 AM

First you need to think about what is a file under /data/security/ ? If it has hard links to a filename in some other location then it's debatable whether the file really qualifies. You can solve this problem by having a filesystem mounted at /data/security/ and nothing mounted below it (making the filesystem and the directory tree the same thing).

Then maybe you want to combine "chroot();chdir();chmod()" into one program so that when it is called with sudo it operates on file(s) under /data/security/ by being chrooted there and has no alternative regardless of the command line provided by the user. That's what I'd call the standard way to do it for a C programmer.

There is also a thing called "posix capabilities" containing CAP_FOWNER (see http://linux.die.net/man/7/capabilities) which looks as if it will allow chmod by users other than the owner. I suspect this is a worse option than the other.

johnmccarthy 02-20-2013 10:49 AM

Not sure what Command to Type to mount to File System
 
linosaurusroot,

Sort of new to Linux. What command should I type to mount the directory as a seperate file system? Is it somthing like mount /data/security?

Take care,
John

linosaurusroot 02-20-2013 12:25 PM

Can you show your /etc/fstab ? And estimate the largest amount of data that might ever exist under /data/security ?

TB0ne 02-20-2013 01:01 PM

Quote:

Originally Posted by johnmccarthy
It seems when I enter smith ALL=NOPASSWD:/bin/chmod 755 /data/security/* smith can perform a chmod on any files, regardless of the directory.

Right, because the way the command is parsed, you're allowing the chmod command. The arguments after it aren't getting shoveled along.
Quote:

Originally Posted by johnmccarthy (Post 4896055)
linosaurusroot,
Sort of new to Linux. What command should I type to mount the directory as a seperate file system? Is it somthing like mount /data/security?

Sorry, but all that is overkill, especially if you only ever want that user to run ONE COMMAND as sudo/root, and it doesn't really address things (or users), that you may want to add in the future.

The easiest thing to do would be for you to write a very small shell script with that one command in it. Make it owned by root:root ("chown root:root /path/to/scriptname"), and permissions of 700 (rwx------) ("chmod 700 /path/to/scriptname"), so that ONLY root can run or edit it. That's it.

In sudoers, restrict them to that one command, and deny ALL OTHERS, as so:
Code:

User_Alias    LIMITEDADMINS = username
LIMITEDADMINS  ALL=(ALL) /path/to/scriptname, /path/to/scriptname2, /sbin/ifconfig

The users in the LIMITEDADMINS group will be able to run the commands listed as root, and nothing else. If the script needs an argument, just have the script read it from the command line, so the user can call it like:
Code:

sudo /path/to/scriptname someargument
...and the "someargument" will get passed to the script, which will take action on it.

If you want more users to do it in the future, just add them to the alias group. More commands? Just add another script/command (comma-separated), and you're done.

linosaurusroot 02-20-2013 01:06 PM

Quote:

Originally Posted by TB0ne (Post 4896160)
Sorry, but all that is overkill, especially if you only ever want that user to run ONE COMMAND as sudo/root .....
LIMITEDADMINS ALL=(ALL) /usr/local/bin/scriptname


He doesn't want them to run only one command. He wants them to chmod files under one directory. Once you put "chmod $1 $2" kind of thing in that script you are doomed.

TB0ne 02-20-2013 01:13 PM

Quote:

Originally Posted by linosaurusroot (Post 4896163)
He doesn't want them to run only one command. He wants them to chmod files under one directory.

...which is ONE COMMAND. The OP posted " can perform a chmod on files located in /data/security/ only?". So, since they only want to perform ONE operation on ONE location....
Quote:

Once you put "chmod $1 $2" kind of thing in that script you are doomed.
Please explain why. Yes, if you just shove that into a script it's a bad thing. If you write the script properly (that is, to check for the path name and/or hard code it in), then the user won't be able to chmod ANY files...just the ones allowed, which solves the problem. In this case, the OP very clearly states that they only want to chmod files located in /data/security. So, part of the script would be:
Code:

chmod /data/security/$1
Which will take only one argument (a file name), and chmod it. Putting in "/etc/sudoers" would then expand to "/data/security/etc/sudoers"...which is invalid, and won't work. A symbolic link from /etc/sudoers to /data/security/sudoers won't work, since the chmod doesn't change the SOURCE file, only the symlink, so they won't magically get rights to sudoers that way.

johnmccarthy 02-20-2013 01:55 PM

linosaurusroot
 
linosaurusroot,

Here you go:
/dev/VolGroup00/LogVol00 / ext3 defaults 1 1
LABEL=/boot /boot ext3 defaults 1 2
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
/dev/VolGroup00/LogVol01 swap swap defaults 0 0

linosaurusroot 02-20-2013 05:14 PM

Quote:

Originally Posted by johnmccarthy (Post 4896193)
/dev/VolGroup00/LogVol00 / ext3 defaults 1 1

OK so with that layout you'll be wanting an ext3-formatted loopback file present on the root partition mounted at /data/security/ .

Code:

#!/bin/sh

umask 022
cd /data/ || exit
[ -d security ] || exit

if [ ! -f storage.ext3 ]
then
    dd if=/dev/zero of=storage.ext3 bs=1M count=100
    chmod 0600 storage.ext3
    mkfs.ext3 -F /data/storage.ext3
fi
[ -d /mnt/ds ] || mkdir -p /mnt/ds
mount -o loop /data/storage.ext3 /mnt/ds || exit
(cd /data/security && tar cf - .) | (cd /mnt/ds && tar xvf -)
umount /mnt/ds
mv -i security OLD-security
mkdir security
mount -o loop /data/storage.ext3 /data/security

and add line to your /etc/fstab for that.
Code:

/data/storage.ext3 /data/security ext3 defaults,loop 1 2

linosaurusroot 02-20-2013 05:41 PM

Quote:

Originally Posted by TB0ne (Post 4896171)
...which is ONE COMMAND. The OP posted " can perform a chmod on files located in /data/security/ only?". So, since they only want to perform ONE operation on ONE location....

We may have been interpreting this differently with
Code:

smith ALL=NOPASSWD:/bin/chmod 755 /data/security/*
meaning either "sudo /bin/chmod 755 /data/security/*" (literally one command) or "sudo /bin/chmod 755 /data/security/foo-bar-and-whatever-chosen-by-the-user" (choice of target but under that directory, possibly in a subdirectory) .

Quote:

Please explain why. Yes, if you just shove that into a script it's a bad thing. If you write the script properly (that is, to check for the path name and/or hard code it in), then the user won't be able to chmod ANY files...just the ones allowed, which solves the problem. In this case, the OP very clearly states that they only want to chmod files located in /data/security. So, part of the script would be:
Code:

chmod /data/security/$1
Which will take only one argument (a file name), and chmod it. Putting in "/etc/sudoers" would then expand to "/data/security/etc/sudoers"...which is invalid, and won't work. A symbolic link from /etc/sudoers to /data/security/sudoers won't work, since the chmod doesn't change the SOURCE file, only the symlink, so they won't magically get rights to sudoers that way.
I'll take it for granted you're testing the name and excluding parent directories (such as "/data/security/" + "../../etc/shadow" meaning "/etc/shadow").

I think you're assuming that only root has write access in /data/security/ (but we've not been told that by OP). If smith (or an accomplice or even an innocent user) writes there you have the possibility of something in that directory being a symbolic link to something outside the directory. It could even become this while the script is running (which is a race condition - what a C programmer might tackle with fchmod()).

I've just tested and chmod does follow symlinks on my system.

Mol_Bolom 02-20-2013 06:04 PM

What about
test -f ${1/*\/} && chmod /specific/directory/here/${1/*\/}

Although, I'm not too knowledgeable on this, but I presume this wouldn't allow any links nor any directories to be modified, as well as would keep anyone from modifying anything in any sub directories.

linosaurusroot 02-20-2013 06:32 PM

Quote:

Originally Posted by Mol_Bolom (Post 4896297)
What about
test -f ${1/*\/} && chmod /specific/directory/here/${1/*\/}

Although, I'm not too knowledgeable on this, but I presume this wouldn't allow any links nor any directories to be modified, as well as would keep anyone from modifying anything in any sub directories.

The test and chmod occur at different times so if someone replaces the file by a symlink at just the right time you've got trouble.

What you'd do in C is open() the file (using its name) then test the file descriptor you had that it was the right one and finally do fchmod() on the descriptor (you don't care about the name at this stage).

Mol_Bolom 02-20-2013 06:53 PM

Quote:

Originally Posted by linosaurusroot (Post 4896309)
The test and chmod occur at different times so if someone replaces the file by a symlink at just the right time you've got trouble.

Ah! Read something similar to that not long ago, just took me one more time reading it (here) to finally get it.

Also, just ran a few tests and found that even using "test -f", for some odd reason, still chmod'ed the linked file.


Quote:

What you'd do in C is open() the file (using its name) then test the file descriptor you had that it was the right one and finally do fchmod() on the descriptor (you don't care about the name at this stage).
After reading and trying all that, then I would have to say writing a specific program seems the safest way to implementing something like this.

chrism01 02-20-2013 11:17 PM

Going back to the original qn, it seems to always be the same cmd for the same target(s).
How about inotify/inotifywait instead?
http://linux.die.net/man/7/inotify
http://linux.die.net/man/1/inotifywait

Alternately, how about changing the program that creates/moves/copies the file, to set the perms when it does so.

johnmccarthy 02-21-2013 11:44 AM

Resolved
 
Please allow me to begin with saying that this site has renewed my faith in the community involvement whose charter is to help others when possible. I think each of your comments above are extrodinary and well thought out along with your constructive critisism many will benefit from those who view this thread. After much thought and consdieration I have decided to implemnet a simple and secure resolution. I have created a script that directs the changes I would have executed if I was at the console. This script can be executed by the general user after performing the sudo command and providing the path and respective script. This script is 700, and located in a folder which the general user can not view (thus not modify).

If I could share the points/credit for solving this problem to all those who replied I would, since each solution would work but based on my limited skill-set and security factors I have implemented TB0ne concept. Going forward I hope to improve my Linux Skills and share everything I know.

Take care,
Johnny Mac

jpollard 02-21-2013 12:59 PM

You also have a problem with shell metacharacters.

consider your "sudo chmod <arbitrary file>"...

What if that arbitrary file is/or contains '`rm -rf /`'.....

When that gets evaluated it will be reprocessed... with privileges.

TB0ne 02-21-2013 01:26 PM

Quote:

Originally Posted by jpollard (Post 4896886)
You also have a problem with shell metacharacters.

consider your "sudo chmod <arbitrary file>"...

What if that arbitrary file is/or contains '`rm -rf /`'.....When that gets evaluated it will be reprocessed... with privileges.

It *COULD*...but again, if the shell script is written to look for/reject such things, it will kick out and die. You've got control of what goes in, and how it's tested.

And there are no perfect solutions to anything like this. There will ALWAYS be holes, as long as there are users. At least in this case, they can only run one shell script, and since it's preceded by sudo, the exact string/command will be logged. If someone does something wrong, it'll be VERY easy to spot, which will be a deterrent. And, if that user can't be trusted with sudo rights, they shouldn't be able to run anything as sudo. There's also a bit of security-through-obfuscation, since the user won't know what's in that shell script, what it looks for/logs, or how it works. Just that it DOES.

jpollard 02-21-2013 07:06 PM

None of that is relevant if the user account gets compromised.

BTW, it is nearly impossible to get a shell script to validate strings properly...

TB0ne 02-22-2013 08:55 AM

Quote:

Originally Posted by jpollard (Post 4897096)
None of that is relevant if the user account gets compromised.

BTW, it is nearly impossible to get a shell script to validate strings properly...

Right. Again, this isn't a perfect solution, just the simplest for what the user needs to do.

As far as I know, there ARE no perfect solutions to security, other than locking your computer in a bank-vault, that only YOU can open, and never connecting it to a network or running any software that you, yourself didn't write.

And if a user account gets compromised, you have problems anyway, no matter which account it is.


All times are GMT -5. The time now is 12:58 PM.