Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

A brief introduction to my question: the command ps will print the information of system processes.

But when I login as root and change the permission x of ps

chmod -x /bin/ps
chmod u+x /bin/ps
ls -l /bin/ps 
-rwxr--r-- 1 root root ...... ps

Then I create a new shell script file call_ps_via_root.sh

#!/bin/bash
ps

and set the x permission

chmod +x /bin/call_ps_via_root.sh
ls -l /bin/call_ps_via_root.sh
-rwxr-xr-x 1 root root ...... call_ps_via_root.sh

After this, I login with a normal user sammy, and I type ps, it will print

Permission denied

and I type /bin/call_ps_via_root.sh

It is still denied. How can I make it work by call_ps_via_root.sh?

share|improve this question

migrated from stackoverflow.com Nov 3 '11 at 12:52

This question came from our site for professional and enthusiast programmers.

1  
Incidentally, why do you first go to such lengths to make sure only root is allowed to run ps and then turn around to try and give users limited root rights for the purpose of running ps? Not criticizing, just wondering what exactly you're trying to accomplish here -- maybe we'll figure out a better way to do itt than this... –  Shadur Nov 3 '11 at 14:33
    
First,I want nobady to use ps except root;second I want to call ps indirectly via some method like calling call_ps_via_root.sh.And I can give different permission to different user by setgid to call_ps_via_root.sh –  sammy Nov 4 '11 at 2:44
2  
... You really need to take a good long look at sudo. And possibly reexamine exactly what you intend to do and what you hope to accomplish with it, because I really fail to see how restricting ps usage is going to help secure your system given that all it does is provide a useful interface to read out information readily available in /proc. –  Shadur Nov 4 '11 at 8:25

4 Answers 4

up vote 7 down vote accepted

You can't: if you make /bin/ps only executable by root, it will be only executable by root. You can't just wrap a script around it to bypass the permission check.

set-user-id

If you want that a normal user calls ps as root you have to look at the set-uid permission. From the setuid article on Wikipedia:

setuid and setgid (short for "set user ID upon execution" and "set group ID upon execution", respectively)1 are Unix access rights flags that allow users to run an executable with the permissions of the executable's owner or group. They are often used to allow users on a computer system to run programs with temporarily elevated privileges in order to perform a specific task. While the assumed user id or group id privileges provided are not always elevated, at a minimum they are specific.

See also the man page of chmod

sudo

If instead you want a normal user to execute something executable by root only use sudo. It will allow you to configure which user will be able to execute what.

share|improve this answer
-rwxr--r-- 1 root root ...... ps

This says that the user who owns it has read, write, and execute permission, and all others just read. So nobody but root can execute ps.

The script you wrote is executable by all, but inherits the permissions from the one who invokes it, so he also gets the "permission denied" when trying to execute the ps, as he is still a normal user.

My guess is that you want to prevent regular users from executing ps with certain options (not that it makes sense to me), but then you have to add the setuid bit or setgid bit to your script (see man page of chmod). When you do this it gets the permissions not from the invoker of the script, but from the one who owns the script.

BUT BEWARE: Setting the suid bit on scripts is inherently insecure. You can do very much with environment variables, that e.g. tell the shell to execute commands - and then they are executed as root (here a custom c-program with the sticky bit is the better solution).

EDIT: Another solution would be to use sudo. Here you can also configure which parameters are allowed to a sudoed program.

EDIT2: Why I think it is not a good idea to prohibit user just from executing ps? As far as I know, all the information ps outputs can be also be acquired via the /proc system - so if you do nothing else it is just security (or whatever you want to achieve) by obfuscation.

share|improve this answer
1  
+1 for sudo. That is the correct way of doing privilege escalation. –  Deleted Nov 3 '11 at 9:20
    
Regarding setuid shell scripts (a bad idea indeeed), see Allow setuid on shell scripts . @ChrisSmith Even sudo needs to be done right. In particular, when giving limited permissions, make sure that sudo only allows a few whitelisted environment variables through. –  Gilles Nov 3 '11 at 22:56

Generally, it's better to use 'sudo'. If you don't have sudo installed and configured

su - someuser -c "/yourscript.sh"
share|improve this answer

Sometimes you want to grant users access to information that is only available using root-tools without giving the user root privileges via sudo. For example to provide the information of a smartctl -A without providing access to the full functionality of smartctl.

Consider for example the program hddtemp. It reads the temperature of a given hard drive from the S.M.A.R.T. data of the drive and prints it to stdout. While you normally need root privileges to do so, it also provides a daemon mode, s.t. the program would run as root, wait in the background for non-root client requests, and forward the output to them whenever they connect the socket. In this fashion you could implement a daemon (started as root) that runs ps and redirects its output whenever the client wants.

Consider this Python example (may need to be ran as root):

import socket, subprocess

HOST = '127.0.0.1'
PORT = 50006

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind((HOST,PORT))
s.listen(1)

while True:
    conn,addr = s.accept()
    pipe = subprocess.Popen(["/bin/ps"],stdout=subprocess.PIPE).stdout
    for line in pipe:
        conn.send(line)
    conn.close()

you may then put a netcat localhost 50006 in your call_ps_via_root.sh and you are done.

share|improve this answer
    
The advantage of this approach is that you have full control over the channel for privilege escalation requests. The downside is that you have to manage your own authentication. If you want to allow a user to run smartctl -A only, configure sudo to allow him to run smartctl -A only. –  Gilles Nov 3 '11 at 22:54

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.