pexpect with apache

Discussion in 'Python' started by half.italian@gmail.com, Oct 18, 2006.

  1. Guest

    Hi all. I try not to post until I am stuck in hole with no way out. I
    fought with this for several hours, and am currently in the hole.

    I'm doing a proof of concept for creating afp shares dynamically
    through a web interface from a client machine. I use a bit of php to
    setup a simple form, and then have the php execute my python script on
    the server. The python script tries to 'su' to root to create the
    share, create dirs, set perms, etc

    The python script alone works fine as 'www'. I can become 'www', run
    it from the command line and the share is made. But when I try to have
    the web server execute it, I continually get a password failure. I'm
    positive the password is correct.

    Any ideas?

    ~Sean D

    ~~~~~~~~~~~test.py
    #! /usr/bin/env python

    import commands, os, P, pexpect

    sharename = sys.argv[1]

    root = "/Users/Shared"
    sharepath = os.path.join(root, sharename)
    password = P.P()

    COMMAND_PROMPT = '[$%#]'
    child = pexpect.spawn('su')
    i = child.expect([pexpect.TIMEOUT, '[Pp]assword:'], timeout=1)
    child.sendline(password.Decrypt(password.sean))

    i = child.expect (['su: Sorry', COMMAND_PROMPT])

    if i == 0:
    print 'Password not accepted'
    sys.exit(1)
    else:
    print "Making dir: %s" % sharepath
    child.sendline("mkdir %s" % sharepath)
    i = child.expect([pexpect.TIMEOUT, COMMAND_PROMPT] ,timeout=1)
    print "Setting group to 'audio'"
    child.sendline("chgrp audio %s" % sharepath)
    i = child.expect([pexpect.TIMEOUT, COMMAND_PROMPT] ,timeout=1)
    print "setting owner to 'audio01'"
    child.sendline("chown audio01 %s" % sharepath)
    i = child.expect([pexpect.TIMEOUT, COMMAND_PROMPT] ,timeout=1)
    print "Opening permissions"
    child.sendline("chmod 777 %s" % sharepath)
    i = child.expect([pexpect.TIMEOUT, COMMAND_PROMPT] ,timeout=1)
    print "sharing -a %s -s 100" % sharepath
    child.sendline("sharing -a %s -s 100" % sharepath)
    i = child.expect([pexpect.TIMEOUT, COMMAND_PROMPT] ,timeout=1)
    sys.exit(0)

    ~~~~~~~~~~~test.php
    <html>
    <body>
    <?php

    if (isset($_GET['sharename'])) {
    $last_line = system("/Users/Shared/test.py {$_GET['sharename']}",
    $retval);
    if ($retval == 0) {
    echo "<br><h2>Mount afp://xxx.xxx.xxx.xxx/{$_GET['sharename']}</h2>";
    } else {
    echo "<br><h2>Failed creating share!</h2>";
    }
    } else {

    echo "<form action='test.php'>";
    echo "<table>";
    echo "<td>Name of share:</td><td><input type='text'
    name='sharename'></td>";
    echo "</table></form>";
    }

    ?>
    </body>
    </html>
     
    , Oct 18, 2006
    #1
    1. Advertising

  2. martdi Guest

    Well, first i don't think it is a good idea to have the python script
    tu su to root, but for it to work, i think (Totally unsure about that)
    www has to be in group wheel to be able to su.

    An other way to make your script run as root is to set the setuid bit
    on your python script to make it run as root, without using su.


    wrote:
    > Hi all. I try not to post until I am stuck in hole with no way out. I
    > fought with this for several hours, and am currently in the hole.
    >
    > I'm doing a proof of concept for creating afp shares dynamically
    > through a web interface from a client machine. I use a bit of php to
    > setup a simple form, and then have the php execute my python script on
    > the server. The python script tries to 'su' to root to create the
    > share, create dirs, set perms, etc
    >
    > The python script alone works fine as 'www'. I can become 'www', run
    > it from the command line and the share is made. But when I try to have
    > the web server execute it, I continually get a password failure. I'm
    > positive the password is correct.
    >
    > Any ideas?
    >
    > ~Sean D
    >
    > ~~~~~~~~~~~test.py
    > #! /usr/bin/env python
    >
    > import commands, os, P, pexpect
    >
    > sharename = sys.argv[1]
    >
    > root = "/Users/Shared"
    > sharepath = os.path.join(root, sharename)
    > password = P.P()
    >
    > COMMAND_PROMPT = '[$%#]'
    > child = pexpect.spawn('su')
    > i = child.expect([pexpect.TIMEOUT, '[Pp]assword:'], timeout=1)
    > child.sendline(password.Decrypt(password.sean))
    >
    > i = child.expect (['su: Sorry', COMMAND_PROMPT])
    >
    > if i == 0:
    > print 'Password not accepted'
    > sys.exit(1)
    > else:
    > print "Making dir: %s" % sharepath
    > child.sendline("mkdir %s" % sharepath)
    > i = child.expect([pexpect.TIMEOUT, COMMAND_PROMPT] ,timeout=1)
    > print "Setting group to 'audio'"
    > child.sendline("chgrp audio %s" % sharepath)
    > i = child.expect([pexpect.TIMEOUT, COMMAND_PROMPT] ,timeout=1)
    > print "setting owner to 'audio01'"
    > child.sendline("chown audio01 %s" % sharepath)
    > i = child.expect([pexpect.TIMEOUT, COMMAND_PROMPT] ,timeout=1)
    > print "Opening permissions"
    > child.sendline("chmod 777 %s" % sharepath)
    > i = child.expect([pexpect.TIMEOUT, COMMAND_PROMPT] ,timeout=1)
    > print "sharing -a %s -s 100" % sharepath
    > child.sendline("sharing -a %s -s 100" % sharepath)
    > i = child.expect([pexpect.TIMEOUT, COMMAND_PROMPT] ,timeout=1)
    > sys.exit(0)
    >
    > ~~~~~~~~~~~test.php
    > <html>
    > <body>
    > <?php
    >
    > if (isset($_GET['sharename'])) {
    > $last_line = system("/Users/Shared/test.py {$_GET['sharename']}",
    > $retval);
    > if ($retval == 0) {
    > echo "<br><h2>Mount afp://xxx.xxx.xxx.xxx/{$_GET['sharename']}</h2>";
    > } else {
    > echo "<br><h2>Failed creating share!</h2>";
    > }
    > } else {
    >
    > echo "<form action='test.php'>";
    > echo "<table>";
    > echo "<td>Name of share:</td><td><input type='text'
    > name='sharename'></td>";
    > echo "</table></form>";
    > }
    >
    > ?>
    > </body>
    > </html>
     
    martdi, Oct 18, 2006
    #2
    1. Advertising

  3. Lee Harr Guest

    > Well, first i don't think it is a good idea to have the python script
    > tu su to root, but for it to work, i think (Totally unsure about that)
    > www has to be in group wheel to be able to su.



    Maybe sudo can help here.
     
    Lee Harr, Oct 18, 2006
    #3
  4. martdi Guest

    Sudo is probably the best solution here, since in the file sudo.conf
    you could restrict the www user only to the python script that requires
    it.

    Also, using either sudo or the setuid flag would remove the need of
    pexpect since all the commands will be run as the designated user.

    for setuid flag:
    chmod u+s pythonScript.py
    chown root pythonScript.py

    for the sudo solution, add an entry to /etc/sudo.conf or /etc/sudoers ,
    depending on distro:
    the syntax for a line in sudo.conf is:
    user hostlist = (userlist) commandlist

    so you might want to add:
    www localhost = NOPASSWD: /var/www/htdocs/pythonScript.py

    note:
    Replace the /var/www/htdocs/pythonScript.py with the path to where
    your script is
    the NOPASSWD: is a flag that tells sudo that no password is
    required

    Lee Harr wrote:
    > > Well, first i don't think it is a good idea to have the python script
    > > tu su to root, but for it to work, i think (Totally unsure about that)
    > > www has to be in group wheel to be able to su.

    >
    >
    > Maybe sudo can help here.
     
    martdi, Oct 18, 2006
    #4
  5. martdi Guest

    Since it wont require pyexpect, and based on the operations you
    accomplish with your python script, maybe that a bash script instead of
    a python one might be the best tool for the job you're trying to
    accomplish.


    martdi wrote:
    > Sudo is probably the best solution here, since in the file sudo.conf
    > you could restrict the www user only to the python script that requires
    > it.
    >
    > Also, using either sudo or the setuid flag would remove the need of
    > pexpect since all the commands will be run as the designated user.
    >
    > for setuid flag:
    > chmod u+s pythonScript.py
    > chown root pythonScript.py
    >
    > for the sudo solution, add an entry to /etc/sudo.conf or /etc/sudoers ,
    > depending on distro:
    > the syntax for a line in sudo.conf is:
    > user hostlist = (userlist) commandlist
    >
    > so you might want to add:
    > www localhost = NOPASSWD: /var/www/htdocs/pythonScript.py
    >
    > note:
    > Replace the /var/www/htdocs/pythonScript.py with the path to where
    > your script is
    > the NOPASSWD: is a flag that tells sudo that no password is
    > required
    >
    > Lee Harr wrote:
    > > > Well, first i don't think it is a good idea to have the python script
    > > > tu su to root, but for it to work, i think (Totally unsure about that)
    > > > www has to be in group wheel to be able to su.

    > >
    > >
    > > Maybe sudo can help here.
     
    martdi, Oct 18, 2006
    #5
  6. Guest

    Thank you both for your help. I don't know why I didn't think of that
    before. I had the expect mindset, and was determined to get it working
    that way.

    I added an entry for sudo for the script and it works without a hitch.
    I'm still curious to know what was going on to disallow the
    authentication in pexpect. I had added 'www' to user 'admin', and
    could su to root from the command line, so I don't think that was it.
    Maybe it was a timing error, ie pexpect fired off the password too soon
    or too late, or something in the apache environment that just
    disallowed becoming root for security reasons.

    Problem solved.

    ~Sean

    martdi wrote:
    > Since it wont require pyexpect, and based on the operations you
    > accomplish with your python script, maybe that a bash script instead of
    > a python one might be the best tool for the job you're trying to
    > accomplish.
    >
    >
    > martdi wrote:
    > > Sudo is probably the best solution here, since in the file sudo.conf
    > > you could restrict the www user only to the python script that requires
    > > it.
    > >
    > > Also, using either sudo or the setuid flag would remove the need of
    > > pexpect since all the commands will be run as the designated user.
    > >
    > > for setuid flag:
    > > chmod u+s pythonScript.py
    > > chown root pythonScript.py
    > >
    > > for the sudo solution, add an entry to /etc/sudo.conf or /etc/sudoers ,
    > > depending on distro:
    > > the syntax for a line in sudo.conf is:
    > > user hostlist = (userlist) commandlist
    > >
    > > so you might want to add:
    > > www localhost = NOPASSWD: /var/www/htdocs/pythonScript.py
    > >
    > > note:
    > > Replace the /var/www/htdocs/pythonScript.py with the path to where
    > > your script is
    > > the NOPASSWD: is a flag that tells sudo that no password is
    > > required
    > >
    > > Lee Harr wrote:
    > > > > Well, first i don't think it is a good idea to have the python script
    > > > > tu su to root, but for it to work, i think (Totally unsure about that)
    > > > > www has to be in group wheel to be able to su.
    > > >
    > > >
    > > > Maybe sudo can help here.
     
    , Oct 19, 2006
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.

Share This Page