Setting file execute permissions--a somewhat arcane question.

As I've been learning Unix, I'm often impressed by the logic and efficiency of certain features, so when I find things that don't fit this pattern, it really makes me wonder.

This particular example isn't so much about the design of permissions as it is about the way administrators--even competent ones--use them.

A case in point:

-rwxr-xr-x 1 root wheel 5099 Dec 7 2006 /usr/sbin/apachectl

This means that the file belongs to root, and root can do anything (s)he wants to it--read, write and execute.

Furthermore, anyone who belongs to the group, wheel (which, correct me if I'm wrong here, is pretty generally confined to root) can read and execute it. They can't write to it because, presumably, you don't want just any old wheel coming along and changing this file, although they may read it, which might be a good thing to do before they execute it.

Finally, other, that is, any old user, can execute the file, but they can't write to it, and they can't even read it. (Incidentally, why would you want to prevent someone from reading a file that you're allowing them to execute? Element of surprise? But that's not my real question.)

My real question involves the following: try logging on as anyone other than root and running that file. If Apache is running, try to stop it. It will tell you it isn't running. That's a lie. Okay, maybe an honest mistake, but it isn't true. Now try to start it. It doesn't have to be stopped; you'll get the same error either way: "fopen: Permission denied," it says, "httpd: could not open error log file /private/var/log/httpd/error_log."

I seem to run into this a lot. A file that I have permission to execute produces an error message when I try to run it because it tries to do something that I don't have permission to do. So why do I have permission to execute the file in the first place?

Okay, maybe there are some useful things I can do with apachectl, like configtest, that don't require me to be root. Like if I'm editing the httpd.conf file, I can check it with configtest, and then when it's ready I can go get an administrator to restart apache, or something like that. Except for the fact that I can't edit httpd.conf because I only have read access to that file. But maybe there are some imaginable scenarios where it might make sense.

But there are other files that you simply can't do a darned thing with, yet which still allow you to execute them and be chastised for your lowly permission status. Not only that, but it's a relatively simple matter to construct a script in such a way that it will check to see who is executing it, while it's processing directives, and return an appropriate error message, e.g. "Sorry, 'stop' and 'start' can only be performed by root," instead of allowing some downstream process to do its dirty work. Incidentally, allowing errors to be returned from downstream processes gives unprivileged users some insight into what the script does, which, presumably, is part of what they're trying to prevent by not allowing them to read the script!

If anyone can shed any light on why things are so often done this way, I'd appreciate it. If not, I guess this is just my Unix rant for the the week.

Disclaimer: I don't hate Unix. I really like it a lot, in spite of its quirks. No one is perfect; not even me! And don't even get me started on "Windows."

MacBook Pro 17, Mac OS X (10.4.10), 4 GB RAM, 160 GB HD

Posted on Aug 19, 2007 9:55 AM

Reply
25 replies

Aug 21, 2007 6:32 PM in response to etresoft

I told myself I wasn't going to respond on this thread again. Then I saw that code. We are amused.


You should have gone with your first impulse. I mean, what's your point? If someone is psychic, and can guess the name of the variable I've used, assuming they even have a clue how the script is written, then they'd be able to defeat something I've put in there to save them the inconvenience of seeing the error message they would have seen anyway if I hadn't bothered?

Gosh! That's terrible! Really good security, of course, would prevent the user from wasting his time even if he's determined to do so.

I am appropriately chastised!

The whole point here, which you've apparently missed, is to tell the user why the script won't run the directive in question, not prevent him from running it. If I wanted to do that I'd just set the permission so that only root can run it.

then, get yourself a good UNIX book and learn how it all works.


I have neither the time nor the need to learn "how it all works." I'm just a user. The author does have good taste in Mac text editors though, even if he is too cheap to pay for the real thing. 🙂

Aug 21, 2007 7:07 PM in response to LittleSaint

This is an interesting thread.


Apparently not. I've been informed that it's trivial. Not to mention not particularly valid. I'm sorry you were misled. 😉

What your running into is the fact that file permissions have little if anything to do with system privileges.


That's another interesting point, but I think my issue only went as far as conflicting file permissions. In the apachectl case, anyway, what the unprivileged user runs into is a log file he doesn't have permission to write to, so he can't start a process that writes to it. The startup scripts for PostgreSQL and MySQL fail for similar reasons, although there the users who own the files are minimally privileged users specially created to run those processes rather than root. This seems to be a general pattern with bootstrap type files.

The file in question here has 755 permissions meaning anyone can read or execute it, only root can make changes. Why? Mostly because that's what everything else gets in /usr/sbin, and there's no reason not to use those permissions. The file permissions have nothing to do with the privileges needed to allow the file to do what it does.


The x-bit has everything to do with the privileges needed to allow the file to do what it does, or ought to anyway. But I take your point about "what everything else gets." I think that might be where the problem comes from. It doesn't necessarily follow that all the scripts in a given location should have the same permissions because they don't do the same things. /usr/sbin executables are generally related to nonessential system services, but that's a pretty broad category. Some are harmless, others aren't.

I think the thing that worries me when I see this is that a script might start doing something--e.g. starting up or shutting down a daemon--but not complete it, leaving it in a sort of twilight state where it appears to be running but can't be connected to, and madness could ensue--madness, I say! 🙂

I haven't found any cases where this actually happens, but it worries me.

A better example is ifconfig. There's a ton of things you can do with it to get information about your network connections, but you have to be root to enable or disable an interface.


Actually, it's a better example of how things should work. If you try to create an interface as a mild-mannered user, you get an error from ifconfig:

ifconfig: SIOCIFCREATE: Operation not permitted

Aug 21, 2007 7:44 PM in response to David Livesay

"The x-bit has everything to do with the privileges needed to allow the file to do what it does, or ought to anyway."

But it doesn't. That's the point. If you want to play in the UNIX sandbox, you have to play by its rules. The x bit determines whether a user can execute the file. It has nothing to do with the privileges the file needs in order to execute some or all of its code. Another interesting example is mount. It can be run by anyone, but it requires root privileges to work. It gets around this because its setuid bit set so it has root (owner) privileges no matter who runs it. Generally this is very dangerous, but mount has a very limited scope in what it can do so it's considered safe. However if you try to mount a volume in a directory you don't have rights to, it will fail because you the user don't have file permission rights to that directory.

Message was edited by: LittleSaint

Aug 21, 2007 8:45 PM in response to LittleSaint

The x bit determines whether a user can execute the file. It has nothing to do with the privileges the file needs in order to execute some or all of its code.


Okay, I see what you mean now. I misread what you said before as "privileges needed +by the user+ to allow the file to do what it does."

But this actually kind of gets to the crux of what I'm complaining about. Since a script essentially just runs commands under the user's login, it can only do what that user can do, so if you write a script that tries to do things that only a specific user or group of users can do, shouldn't you limit its executability to just those users?

It gets around this because its setuid bit set so it has root (owner) privileges no matter who runs it.


Wow. I didn't know you could do this. That is kind of scary. =:-o

Aug 21, 2007 9:17 PM in response to David Livesay

Hi David,
Not only do the permissions required to successfully run apachectl not need to correspond to the script's permissions, as LittleSaint points out, but arranging that would be exceedingly difficult. The permissions required to start the web server are completely dependent on what's in the /etc/httpd/httpd.conf file. It's easy to configure the web server so that user "nobody" (or any other user for that matter) has sufficient privileges to run it. Even if you rewrite the apachectl script to read the httpd.conf file before starting the daemons and test for required privileges, the script isn't likely change its own permissions. Even if you rewrite it to change its own permissions, it would seem a colossal waste of time. It's too easy to find out if you have the required privileges by simply trying to start the web server, which you did. I don't see what the problem is.
--
Gary
~~~~
Q: How many IBM 370's does it take to execute a job?
A: Four, three to hold it down, and one to rip its head off.

Aug 21, 2007 9:31 PM in response to David Livesay

David Livesay wrote:
You should have gone with your first impulse. I mean, what's your point?


My point is that if you are really using that code, you should change it. The variable EUID would be a better choice. You called this thread a "rant" yourself when you started it 🙂

I have neither the time nor the need to learn "how it all works." I'm just a user.


If you are writing scripts, you are a developer. If you are considering messing about in security, then you have a responsibility to know how it all works.

You asked why Unix is this way and we've tried to explain what Thompson and Ritchie were thinking when they wrote it almost 40 years ago. People (including Apple) have tried to improve upon it many times, usually without success.

You are absolutely correct in that it is far better to perform permission checks up front than to get started and fail, possibly leaving resources hanging. Unfortunately, that rarely happens in practice. The average level of code quality is pretty low, from what I've seen.

Aug 21, 2007 11:12 PM in response to David Livesay

Your gripe with the permissions on apachectl is trivial and not particularly valid.


Sorry I wasted your time then. Next time you can just pass by my post without reading it. How's that?


No way. That would deprive me of quality entertainment. Did you ask about this to learn something, or just to gripe about stuff you don't understand? For a guy who doesn't understand how it all works, you sure seem to have some strong opinions about how it should.

I have to agree with etresoft. We are amused with your code fragment. You obviously have many days, perhaps even weeks of unix experience. If you'd like that code to work, you might try using $UID instead. Of course, that'd be silly too. If you want to accomplish that, you'd say ...

bash# chown root program
bash# chmod 700 program

... and leave the code alone.

You barely understand the basics of file modes. Just learned about setuid and setgid bits today? Then you couldn't possibly be hip to what they mean on a directory as opposed to a plain file. And I'd be very surprised if you knew that every process has a real uid and an effective uid.

IMHO, you have a lot to learn. You don't seem to think so.

I have neither the time nor the need to learn "how it all works."


I want to play piano, but I don't want to know anything about music.

Aug 22, 2007 9:58 AM in response to Gary Kerbaugh

Gary,

I wasn't suggesting what you're describing. My inclination would be to assign rwx------ or rwxr-x--- (which are practically the same thing since root is the only user in wheel) so no one other than root can run it, because no one but root can run it to any useful effect in the default configuration. Anyone who would be capable of modifying httpd.conf would have to have root permissions; therefore, they would be capable of modifying apachectl or changing its mode at their discretion.

The only thing you gain by giving others execute permission is that they can run apachectl configtest, but there's not much value in that since they can't change the configuration anyway. Even the /private/etc/httpd/users/*.config files are owned by root and are only writable by the owner. The group and other permissions aren't even needed to allow users to stop and start the server via the control panel.

Aug 22, 2007 12:47 PM in response to David Livesay

You're free to change default permissions at your own peril, but I don't really see what you're trying to accomplish here. If a user runs something that needs root privileges, they will get an error. If you remove the execute bit, they will get an error. What's the point? You're not increasing security in any way. Your only adding complexity to a system designed by those much smarter than you or me (though I'll never admit it)

As you stated there is functionality there that does not require root privileges which is the whole point of having the "other" execute bit set.

Aug 23, 2007 6:59 PM in response to LittleSaint

Sure, you can change it, but "Repair Permissions" sets it right back.

The reason for changing the permissions is to give the user an error message that makes sense. If a user tries to start apache without using sudo, they get this:

% apachectl stop
/usr/sbin/apachectl stop: httpd (pid 2483?) not running

That's misleading. Apache actually is running. How is the user supposed to connect this message with a permissions setting? I think it's a lot more useful to get a "Permission denied" error, and not the "fopen: Permission denied" error you get when you try to start Apache. That's not quite as misleading, but it's still confusing.

I know Unix wasn't designed to be user-friendly, but this seems more like a case of going out of the way to be user-unfriendly.

This thread has been closed by the system or the community team. You may vote for any posts you find helpful, or search the Community for additional answers.

Setting file execute permissions--a somewhat arcane question.

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple Account.