1

Hi I have a python script which modifies an application configuration file. To applied this, I need to restart the application. To do that I call a init.d file. But I need to be root when I do this action otherwise the application cannot bind her on the port. Also I dont want execute all my python script with the root's privileges. How can I execute the restart with the root privileges and then remove them.

I set the user permission at the beginning with:

if __name__ == "__main__":
    uid = pwd.getpwnam('ubuntu')[2]
    os.setuid(uid)
    app.run(host='0.0.0.0', port=5001, debug=True)

and at the end of my script I need to execute:

commands.getoutput('/etc/init.d/webapplication restart')

webapplication binds on the port 80.

If I execute my script with this configuration, webapplication cant start and return a message, "cannot bind socket on the 80".

Any idea? to have a clean solution to execute only one external command with the root privileges on a Debian server under a python script?

Thansk in advance.

P.S: I have tried to use the same method like in my main function and I have replaced the user "ubuntu" by "root" but it's not work.

Matt
  • 4,309
  • 7
  • 38
  • 52
  • User who want execute you file is in ´sudoers´ list?. If your user is in sudoers list you can change things. But, you need root privileges for change/modify Init Services. Did you try add your user into root group? – ManuParra Mar 02 '13 at 23:17
  • related: [Is there a way for non-root processes to bind to “privileged” ports (<1024) on Linux?](http://stackoverflow.com/q/413807/4279) – jfs Mar 03 '13 at 00:33

2 Answers2

0

You can use either of two approaches:

  1. Create a program whose only job is to run the init.d script, and make it setuid root. (Make sure to write it securely!). The main script runs with ordinary user permissions and calls the runner.

  2. There's no way for a program to escalate its own privileges (except by running sudo, which is at least as expensive as approach 1), but a program running as root can de-escalate itself. So you can do some steps as root and then continue as the normal user by setting your uid down to the real uid. This won't be any help if you need root privileges for the last thing the program does, though.

alexis
  • 48,685
  • 16
  • 101
  • 161
  • Thanks for your answer. The problem is that, only the root user can use setuid. Actually if I run my main script with root user privileges, at the beginning of the script, I have use setuid with my custom user. And at the end my script, I call another module witch try to setuid on the root user. Well with this method I have an error on the execution of the second setuid: "OSError: [Errno 1] Operation not permitted" – Matt Mar 03 '13 at 18:03
  • I'm sorry, I don't understand what you're trying to say. But yes, only root can change uid, that's what I explained. Use one of the approaches I propose. – alexis Mar 04 '13 at 00:16
0

Finaly to reach my goal, I have use the sudo solution. To do that on a debian server:

apt-get install sudo
Edit: /etc/sudoers
Add line: my_user(uses for the setuid) ALL = NOPASSWD : /etc/init.d/webapplication
And in my python script:
commands.getoutput('sudo /etc/init.d/webapplication restart')    

And that works.

Matt
  • 4,309
  • 7
  • 38
  • 52