[Chicago-talk] mkdir() question

Young, Darren Darren.Young at chicagobooth.edu
Thu Dec 2 12:16:56 PST 2010


I need some ideas on a problem I'm having doing mkdir and chown in Perl. The Perl script I have is running as a CGI under Apache 2.2.3 (RHEL). This script is the receiving end of a web service using SOAP::Lite (client is C# .NET). This script needs to do a mkdir for a user home directory and change permissions on it to that of the user (and their primary GID). 

Problem is Apache is running as the user "apache" (as it should) and therefore the script has no permissions do to a mkdir on /export/home. I haven't even gotten to the chown part, which if memory serves me correctly, won't work unless the script is being run as root. Can't change ownership of a directory to something other than yourself if you're not root right?

I've considered the options of setuid-perl (argh), running the web server as something else (ugh) suexec under Apache or even setting the permissions on /export/home to that of apache. Though the latter won't solve the chown problem.

Anyone have any other thoughts before I hang myself with setuid root?

Darren Young

Here's the worker code:

###############################################################################
# NAME        : _make_homedir
# DESCRIPTION : Create a user home directory
# ARGUMENTS   : string(username), string(uid), string(type)
# RETURN      : 0 or 1
# NOTES       : 
###############################################################################
sub _make_homedir {
    my ( $uname, $uid, $actype ) = @_;
    my $name = "_make_homedir";
    logging::logmsg(STDERR, "$name: entering _make_homedirs()");

    my $homedir   = $config::GCH_HOMEDIR{$actype} . "/$uname";
    my @skelfiles = ( '.cshrc', '.login', '.profile' );
    my $skelbase  = "$FindBin::Bin/skel";
    my $gid       = $config::GCH_GID{$actype};
    my $retval    = 1;

    ### Log the info
    logging::logmsg(STDERR, "$name: homedir  => $homedir");
    logging::logmsg(STDERR, "$name: skelbase => $skelbase");
    logging::logmsg(STDERR, "$name:      gid => $gid");

    ##############################################################################
    ### Create the home directory
    ##############################################################################
    logging::logmsg(STDERR, "$name: Attempting to create directory: $homedir");
    if ( !-d $homedir ) {
        if ( mkdir( "$homedir", 0720 ) ) {
            logging::logmsg(STDERR, "$name: Created home directory: $homedir");
        } else {
		my $err = "FAILED to create home directory $homedir: $!";
            logging::logmsg(STDERR, "$name: $err");
            die($err);
        }
    } else {
	  my $err = "FAILED to create directory $homedir: $homedir already exists";
        logging::logmsg(STDERR, "$name: $err");
        die("$err");
    }


    ##############################################################################
    ### Change the ownership on the home directory
    ##############################################################################
    logging::logmsg(STDERR, "$name: Attempting to change ownership on: $homedir");
    my $cnt = 0;
    $cnt = chown $uid, $gid, $homedir;
    if ( $cnt != 1 ) {
	  my $err = "FAILED - home directory $homedir ownership not changed: $!";
        logging::logmsg(STDERR, "$name: $err");
        die($err);
    } else {
        logging::logmsg(STDERR, "$name: $homedir ownership changed to $uid:$gid");
        $retval = 1;
    }


    ##############################################################################
    ### Copy all the skel files and set their perms
    ##############################################################################
    foreach my $file (@skelfiles) {
        if ( !copy( "$skeldir/$file", "$homedir" ) ) {
            logging::logmsg(STDERR, "$name: FAILED to copy $skeldir/$file to $homedir");
            $retval = 0;
        } else {
            logging::logmsg(STDERR, "$name: Copied $skeldir/$file to $homedir");
		$retval = 1;
		}

        $cnt = chown $uid, $gid, "$homedir/$file";
        if ( $cnt != 1 ) {
            logging::logmsg(STDERR, "$name: FAILED to set perms on: $homedir/$file");
            $retval = 0;
        } else {
            logging::logmsg(STDERR, "$name: Set permissions on $homedir/$file");
		$retval = 1;
		}
    }

    logging::logmsg(STDERR, "$name: returning with value: $retval");
    return ($retval);
}



More information about the Chicago-talk mailing list