Archive

Archive for July, 2009

Sticky files and Python

July 24th, 2009 1 comment

I am currently writing a lot of file manipulation code and keep running into snags that’s led to a lot of interesting debugging…

The most recent issues have been with editing files with interesting permissions set. I’ve been messing with the sticky bit, which you trigger so that the files owner is the user that runs the application regardless of who actaully runs the application.

The situation I’m interested in here, is that I set a file to be owned by a user named ‘admin’ and set the sticky bit to active (so that the file would always be run by ‘admin’). Then I tried running that file, and having that script manipulate a file for which it needed to be the user ‘admin’, and that failed, since the file was actually not being run by the ‘admin’ user.

After a bunch of debugging I realized that although the script is set to the ‘admin’ user, the actual thing running the application is the Python interpreter, which is being run by my logged in user (not the ‘admin’ user’).

The following code snippets will take you through the scenario so that you can reproduce and feel the silly complexity of Linux file manipulation on your own.

Let’s say our file is named ‘sticky’ and we are just going to work in our current directory:

> ls -ld sticky
-rw-rw-rw-   1   my_user   group   1K 2009-07-24 12:00 sticky

> sudo chown admin:group sticky
> sudo chmod 750 sticky
> sudo chmod ug+s sticky

> ls -ld sticky
-rwsr-s---   1   admin   group   1K 2009-07-24 12:00 sticky

> ./my_python_script.py

Right there is where my problem happened. I couldn’t run any of the file manipulation stuff on the ‘sticky’ file, even though my script had its sticky bits set and its owner was the same as that of the file I wanted to manipulate. One way around this is to write a wrapper in C++ that then calls your Python script. As such:

my_cpp.cpp:

#include <sstream>
#include <cstdlib>
#include <iostream>
#include <errno.h>
using namespace std;

int main(int argc, char **argv)
{
    string cmd = "./my_python_script.py";
    int return_code = execvp(cmd.c_str(), argv);

    if (-1 == return_code)
        cout<<errno<<": "<<strerror(errno)<<endl;

    return 0;
}

my_python.py:

print "Inside Python file"

You would run your code as such:

> chmod 750 my_python.py my_cpp.cpp
> g++ my_cpp.cpp -o my_runner
> my_runner
Categories: Uncategorized Tags: