return $text;
}
+/**
+ * util_create_file_with_contents() — Securely create (or replace) a file with given contents
+ *
+ * @param string $path Path of the file to be created
+ * @param string $contents Contents of the file
+ *
+ * @return boolean FALSE on error
+ */
+function util_create_file_with_contents($path, $contents) {
+ if (file_exists($path) && !unlink($path)) {
+ return false;
+ }
+ $handle = fopen($path, "x+");
+ if ($handle == false) {
+ return false;
+ }
+ fwrite($handle, $contents);
+ fclose($handle);
+}
+
+/**
+ * Create a directory in the system temp directory with a hard-to-predict name.
+ * Does not have the guarantees of the actual BSD libc function or Python tempfile function.
+ * @param string $suffix Append to the new directory's name
+ * @param string $prefix Prepend to the new directory's name
+ * @return string The path of the new directory.
+ *
+ * Mostly taken from https://gist.github.com/1407245 as a "temporary"
+ * workaround to https://bugs.php.net/bug.php?id=49211
+ */
+function util_mkdtemp($suffix = '', $prefix = 'tmp') {
+ $tempdir = sys_get_temp_dir();
+ for ($i=0; $i<5; $i++) {
+ $id = strtr(base64_encode(openssl_random_pseudo_bytes(6)), '+/', '-_');
+ $path = "{$tempdir}/{$prefix}{$id}{$suffix}";
+ if (mkdir($path, 0700)) {
+ return $path;
+ }
+ }
+ return false;
+}
+
+/**
+ * Run a function with only the permissions of a given Unix user
+ * Function can be an anonymous
+ * Optional arguments in an array
+ * @param string Unix user name
+ * @param function function to run (possibly anonymous)
+ * @param array parameters
+ * @return boolean true on success, false on error
+ */
+function util_sudo_effective_user($username, $function, $params=array()) {
+ $saved_egid = posix_getegid();
+ $saved_euid = posix_geteuid();
+
+ $userinfo = posix_getpwnam($username);
+ if ($userinfo === False) {
+ return False;
+ }
+ if (posix_setegid($userinfo['gid']) && posix_seteuid($userinfo['uid'])) {
+ $function($params);
+ }
+
+ posix_setegid($saved_egid);
+ posix_seteuid($saved_euid);
+}
// Local Variables:
// mode: php
+++ /dev/null
-diff -Nur -x '*.orig' -x '*.rej' gforge-3.0pre9/utils/create-cvs-repository.sh mezzanine_patched_gforge-3.0pre9/utils/create-cvs-repository.sh
---- gforge-3.0pre9/utils/create-cvs-repository.sh Wed Dec 31 19:00:00 1969
-+++ mezzanine_patched_gforge-3.0pre9/utils/create-cvs-repository.sh Fri Jan 24 18:19:03 2003
-@@ -0,0 +1,70 @@
-+#!/bin/sh
-+#
-+# CVS Repository Tool
-+# (c)1999 SourceForge Development Team
-+# Released under the GPL, 1999
-+#
-+
-+CVS="cvs"
-+PATH="/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin"
-+
-+# Read config info, if any
-+for i in /etc/gforge/env /etc/sysconfig/gforge /etc/sysconfig/cvs
-+ test -f $i && . $i
-+done
-+
-+# Set the variable for our CVS tree if not set already
-+if [ "x$CVSTREETOP" = "x" ]; then
-+ CVSTREETOP=/usr/share/gforge/cvsroot
-+fi
-+
-+# if no arguments, print out help screen
-+if test $# -lt 2; then
-+ echo "usage:"
-+ echo " $0 [repositoryname] [groupid]"
-+ echo ""
-+ exit 1
-+fi
-+
-+# make sure this repository doesn't already exist
-+if [ -d ${CVSTREETOP}/$1 ] ; then
-+ echo "$1 already exists."
-+ echo ""
-+ exit 1
-+fi
-+
-+# first create the repository
-+mkdir ${CVSTREETOP}/$1
-+$CVS -d${CVSTREETOP}/$1 init
-+
-+# make it group writable
-+chmod 775 ${CVSTREETOP}/$1
-+
-+# import default directory, with default cvs.txt
-+#mkdir $1
-+#cp cvs.txt $1
-+#cd $1
-+#$CVS -d${CVSTREETOP}/$1 import -m "SourceForge CVStool creation" $1 SourceForge start
-+#rm cvs.txt
-+#cd ..
-+#rmdir $1
-+
-+# turn off pserver writers, on anonymous readers
-+echo > ${CVSTREETOP}/$1/CVSROOT/writers
-+echo "anonymous" > ${CVSTREETOP}/$1/CVSROOT/readers
-+echo "anonymous:\$1\$0H\$2/LSjjwDfsSA0gaDYY5Df/:anoncvs_$1" > ${CVSTREETOP}/$1/CVSROOT/passwd
-+
-+# setup loginfo to make group ownership every commit
-+echo "ALL chgrp -R $1 ${CVSTREETOP}/$1" > ${CVSTREETOP}/$1/CVSROOT/loginfo
-+echo > ${CVSTREETOP}/$1/CVSROOT/val-tags
-+chmod 664 ${CVSTREETOP}/$1/CVSROOT/val-tags
-+
-+# set group ownership, anonymous group user
-+chown -R nobody:$2 ${CVSTREETOP}/$1
-+
-+# Create/modify anoncvs account
-+if ! id -u anoncvs_$1 >/dev/null 2>&1; then
-+ useradd -g $2 -d${CVSTREETOP}/$1 -c "$1 Anonymous CVS User" -s /bin/false -M anoncvs_$1
-+else
-+ usermod -g $2 -d${CVSTREETOP}/$1 -c "$1 Anonymous CVS User" -s /bin/false anoncvs_$1
-+fi
-diff -Nur -x '*.orig' -x '*.rej' gforge-3.0pre9/utils/create-cvs-tarballs.sh mezzanine_patched_gforge-3.0pre9/utils/create-cvs-tarballs.sh
---- gforge-3.0pre9/utils/create-cvs-tarballs.sh Wed Dec 31 19:00:00 1969
-+++ mezzanine_patched_gforge-3.0pre9/utils/create-cvs-tarballs.sh Fri Jan 24 18:15:00 2003
-@@ -0,0 +1,42 @@
-+#!/bin/sh
-+#
-+# Create tarballs of individual CVS repositories nightly
-+#
-+# 24 January 2003
-+# Michael Jennings
-+#
-+
-+CVS="cvs"
-+PATH="/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin"
-+TAR="tar"
-+#TAR="gtar"
-+GZIP="gzip"
-+#GZIP="gzip -9"
-+
-+# Read config info, if any
-+for i in /etc/gforge/env /etc/sysconfig/gforge /etc/sysconfig/cvs
-+ test -f $i && . $i
-+done
-+
-+# Set the variable for our CVS tree if not set already
-+if [ "x$CVSTREETOP" = "x" ]; then
-+ CVSTREETOP=/usr/share/gforge/cvsroot
-+fi
-+
-+# Set the variable for where to put our tarballs if not set already
-+if [ "x$CVSTARBALLS" = "x" ]; then
-+ CVSTARBALLS=/usr/share/gforge/www/cvstarballs
-+fi
-+
-+# Make sure the place we want to put these things exists.
-+if [ ! -d $CVSTARBALLS ]; then
-+ mkdir $CVSTARBALLS
-+ chmod 755 $CVSTARBALLS
-+fi
-+
-+# Create the tarballs
-+cd $CVSTREETOP
-+for i in ???* ; do
-+ test -d $i/CVSROOT || continue
-+ $TAR -cf - $i/ | $GZIP -c > $CVSTARBALLS/$i-cvsroot.tar.gz
-+done
-diff -Nur -x '*.orig' -x '*.rej' gforge-3.0pre9/utils/cvs.txt mezzanine_patched_gforge-3.0pre9/utils/cvs.txt
---- gforge-3.0pre9/utils/cvs.txt Wed Jan 15 19:16:46 2003
-+++ mezzanine_patched_gforge-3.0pre9/utils/cvs.txt Wed Dec 31 19:00:00 1969
-@@ -1 +0,0 @@
--Welcome to your SourceForge CVS Repository.
-diff -Nur -x '*.orig' -x '*.rej' gforge-3.0pre9/utils/cvs1/cvscreate.sh mezzanine_patched_gforge-3.0pre9/utils/cvs1/cvscreate.sh
---- gforge-3.0pre9/utils/cvs1/cvscreate.sh Wed Jan 15 19:16:46 2003
-+++ mezzanine_patched_gforge-3.0pre9/utils/cvs1/cvscreate.sh Wed Dec 31 19:00:00 1969
-@@ -1,55 +0,0 @@
--#!/bin/sh
--echo ""
--echo "CVS Repository Tool"
--echo "(c)1999 SourceForge Development Team"
--echo "Released under the GPL, 1999"
--echo ""
--
--# if no arguments, print out help screen
--if test $# -lt 2; then
-- echo "usage:"
-- echo " cvscreate.sh [repositoryname] [groupid]"
-- echo ""
-- exit 1
--fi
--
--# make sure this repository doesn't already exist
--if [ -d /cvsroot/$1 ] ; then
-- echo "$1 already exists."
-- echo ""
-- exit 1
--fi
--
--# first create the repository
--mkdir /cvsroot/$1
--cvs -d/cvsroot/$1 init
--
--# make it group writable
--chmod 775 /cvsroot/$1
--
--# import default directory, with default cvs.txt
--#mkdir $1
--#cp cvs.txt $1
--#cd $1
--#cvs -d/cvsroot/$1 import -m "SourceForge CVStool creation" $1 SourceForge start
--#rm cvs.txt
--#cd ..
--#rmdir $1
--
--# turn off pserver writers, on anonymous readers
--echo "" > /cvsroot/$1/CVSROOT/writers
--echo "anonymous" > /cvsroot/$1/CVSROOT/readers
--echo "anonymous:\$1\$0H\$2/LSjjwDfsSA0gaDYY5Df/:anoncvs_$1" > /cvsroot/$1/CVSROOT/passwd
--
--# setup loginfo to make group ownership every commit
--echo "ALL chgrp -R $1 /cvsroot/$1" > /cvsroot/$1/CVSROOT/loginfo
--echo "" > /cvsroot/$1/CVSROOT/val-tags
--chmod 664 /cvsroot/$1/CVSROOT/val-tags
--
--# set group ownership, anonymous group user
--chown -R nobody:$2 /cvsroot/$1
--cat /etc/passwd | grep -v anoncvs_$1 > newpasswd
--cp newpasswd /etc/passwd
--rm -f newpasswd
--/usr/sbin/adduser -M -g $2 -d/cvsroot/$1 -s /bin/false -n anoncvs_$1
--
-diff -Nur -x '*.orig' -x '*.rej' gforge-3.0pre9/utils/cvs1/cvstar_genlist.pl mezzanine_patched_gforge-3.0pre9/utils/cvs1/cvstar_genlist.pl
---- gforge-3.0pre9/utils/cvs1/cvstar_genlist.pl Wed Jan 15 19:16:46 2003
-+++ mezzanine_patched_gforge-3.0pre9/utils/cvs1/cvstar_genlist.pl Wed Dec 31 19:00:00 1969
-@@ -1,9 +0,0 @@
--#!/usr/bin/perl
--echo ""
--echo "CVSTar List Generator"
--echo "(c)1999 VA Linux Systems"
--echo ""
--
--$rawlist = `ls /cvsroot/*`;
--
--
-diff -Nur -x '*.orig' -x '*.rej' gforge-3.0pre9/utils/cvs1/cvstar_superscript.pl mezzanine_patched_gforge-3.0pre9/utils/cvs1/cvstar_superscript.pl
---- gforge-3.0pre9/utils/cvs1/cvstar_superscript.pl Wed Jan 15 19:16:46 2003
-+++ mezzanine_patched_gforge-3.0pre9/utils/cvs1/cvstar_superscript.pl Wed Dec 31 19:00:00 1969
-@@ -1,12 +0,0 @@
--#!/usr/bin/perl
--echo ""
--echo "CVSTar SuperScript"
--echo "(c)1999 VA Linux Systems"
--echo ""
--
--use DBI;
--require("include.pl");
--
--&db_connect;
--
--
-diff -Nur -x '*.orig' -x '*.rej' gforge-3.0pre9/utils/gforge-hourly-cronjobs.sh mezzanine_patched_gforge-3.0pre9/utils/gforge-hourly-cronjobs.sh
---- gforge-3.0pre9/utils/gforge-hourly-cronjobs.sh Wed Dec 31 19:00:00 1969
-+++ mezzanine_patched_gforge-3.0pre9/utils/gforge-hourly-cronjobs.sh Fri Jan 24 16:42:02 2003
-@@ -0,0 +1,20 @@
-+#!/bin/sh
-+#
-+# Run all GForge hourly cronjobs in the proper order.
-+# (Based on original SourceForge sample crontab.)
-+#
-+# 24 January 2003
-+# Michael Jennings <mej@eterm.org>
-+#
-+
-+GFORGE_ROOT="/usr/share/gforge"
-+CRON_DIR="$GFORGE_ROOT/cronjobs"
-+PHP="/usr/bin/php"
-+RUN_AS="gforge"
-+
-+if [ "`id -n -u`" != "$RUN_AS" ]; then
-+ exec su -l $RUN_AS -s $SHELL -c "$0"
-+fi
-+
-+### Send pending mass-mailings, if any.
-+# $PHP $CRON_DIR/massmail.php
-diff -Nur -x '*.orig' -x '*.rej' gforge-3.0pre9/utils/gforge-nightly-cronjobs.sh mezzanine_patched_gforge-3.0pre9/utils/gforge-nightly-cronjobs.sh
---- gforge-3.0pre9/utils/gforge-nightly-cronjobs.sh Wed Dec 31 19:00:00 1969
-+++ mezzanine_patched_gforge-3.0pre9/utils/gforge-nightly-cronjobs.sh Fri Jan 24 17:04:28 2003
-@@ -0,0 +1,50 @@
-+#!/bin/sh
-+#
-+# Run all nightly GForge cronjobs in the proper order
-+# (Based on original SourceForge sample crontab.)
-+#
-+# 24 January 2003
-+# Michael Jennings <mej@eterm.org>
-+#
-+
-+GFORGE_ROOT="/usr/share/gforge"
-+CRON_DIR="$GFORGE_ROOT/cronjobs"
-+PHP="/usr/bin/php"
-+RUN_AS="gforge"
-+
-+if [ "`id -n -u`" != "$RUN_AS" ]; then
-+ exec su -l $RUN_AS -s $SHELL -c "$0"
-+fi
-+
-+### daily rotation of the activity_log
-+$PHP $CRON_DIR/rotate_activity.php
-+
-+### daily aggregating of the numbers
-+$PHP $CRON_DIR/site_stats.php
-+
-+### recalculate user popularity metric
-+$PHP $CRON_DIR/calculate_user_metric.php
-+
-+### daily project_weekly_metric recalc
-+$PHP $CRON_DIR/project_weekly_metric.php
-+
-+### daily deletion of sessions, closing jobs, etc
-+$PHP $CRON_DIR/project_cleanup.php
-+
-+### daily crunching of survey data and other associated ratings
-+$PHP $CRON_DIR/rating_stats.php
-+
-+### daily crunching of project summary data (counts)
-+$PHP $CRON_DIR/db_project_sums.php
-+
-+### daily recalculate of the sums under the trove map
-+$PHP $CRON_DIR/db_trove_maint.php
-+
-+### daily close pending artifacts
-+$PHP $CRON_DIR/check_stale_tracker_items.php
-+
-+### Stats aggregation work
-+$PHP $CRON_DIR/db_stats_agg.php
-+
-+### VACUUM should be done after ALL OTHER JOBS
-+$PHP $CRON_DIR/vacuum.php
@mkdir(forge_get_config('ftp_upload_dir'),0755,true);
}
+//
+// Read in the template file
+//
+$fo=fopen(dirname(__FILE__).'/../utils/default_page.php','r');
+$default_contents = '';
+if (!$fo) {
+ $err .= 'Default Page Not Found';
+} else {
+ while (!feof($fo)) {
+ $default_contents .= fread($fo, 8192);
+ }
+ fclose($fo);
+}
+
+function create_dirs_and_files($params) {
+ $project = $params['project'];
+ $groupname = $project->getUnixName();
+ $default_contents = $parmas['default_contents'];
+
+ mkdir(forge_get_config('groupdir_prefix')."/".$groupname."/htdocs");
+ mkdir(forge_get_config('groupdir_prefix')."/".$groupname."/cgi-bin");
+
+ $contents = $default_contents;
+ //
+ // Change some defaults in the template file
+ //
+ $contents=str_replace('##comment##', _('Default Web Page for groups that haven\'t setup their page yet'), $contents);
+ $contents=str_replace('##purpose##', _('Please replace this file with your own website'), $contents);
+ $contents=str_replace('##welcome_to##', sprintf(_('Welcome to %s'), $project->getPublicName()), $contents);
+ $contents=str_replace('##body##',
+ sprintf(
+ _("We're Sorry but this Project hasn't yet uploaded their personal webpage yet. <br /> Please check back soon for updates or visit <a href=\"%s\">the project page</a>."),
+ util_make_url ('/projects/'.$project->getUnixName())),
+ $contents);
+ //
+ // Write the file back out to the project home dir
+ //
+ $fw=fopen(forge_get_config('groupdir_prefix')."/".$groupname."/htdocs/index.html",'w');
+ fwrite($fw,$contents);
+ fclose($fw);
+
+ if (forge_get_config('use_manual_uploads')) {
+ $incoming = forge_get_config('groupdir_prefix')."/".$groupname."/incoming" ;
+ if (!is_dir($incoming))
+ {
+ mkdir($incoming);
+ }
+ }
+}
+
foreach($active_projects as $project) {
$groupname = $project->getUnixName() ;
//create an FTP upload dir for this project
} else {
@mkdir(forge_get_config('groupdir_prefix')."/".$groupname);
- @mkdir(forge_get_config('groupdir_prefix')."/".$groupname."/htdocs");
- @mkdir(forge_get_config('groupdir_prefix')."/".$groupname."/cgi-bin");
-
- //
- // Read in the template file
- //
- $fo=fopen(dirname(__FILE__).'/../utils/default_page.php','r');
- $contents = '';
- if (!$fo) {
- $err .= 'Default Page Not Found';
- } else {
- while (!feof($fo)) {
- $contents .= fread($fo, 8192);
- }
- fclose($fo);
- }
- //
- // Change some defaults in the template file
- //
- $contents=str_replace('##comment##', _('Default Web Page for groups that haven\'t setup their page yet'), $contents);
- $contents=str_replace('##purpose##', _('Please replace this file with your own website'), $contents);
- $contents=str_replace('##welcome_to##', sprintf(_('Welcome to %s'), $project->getPublicName()), $contents);
- $contents=str_replace('##body##',
- sprintf(
- _("We're Sorry but this Project hasn't yet uploaded their personal webpage yet. <br /> Please check back soon for updates or visit <a href=\"%s\">the project page</a>."),
- util_make_url ('/projects/'.$project->getUnixName())),
- $contents);
- //
- // Write the file back out to the project home dir
- //
- $fw=fopen(forge_get_config('groupdir_prefix')."/".$groupname."/htdocs/index.html",'w');
- fwrite($fw,$contents);
- fclose($fw);
+ system("chown ".forge_get_config('apache_user').":".forge_get_config('apache_group')." ".forge_get_config('groupdir_prefix')."/".$groupname);
}
- if (forge_get_config('use_manual_uploads')) {
- $incoming = forge_get_config('groupdir_prefix')."/".$groupname."/incoming" ;
- if (!is_dir($incoming))
- {
- @mkdir($incoming);
- }
- }
-
- system("chown -R ".forge_get_config('apache_user').":".forge_get_config('apache_group')." ".forge_get_config('groupdir_prefix')."/".$groupname);
-
+ $params = array();
+ $params['project'] = $project;
+ $params['default_contents'] = $default_contents;
+
+ util_sudo_effective_user(forge_get_config('apache_user'),
+ "create_dirs_and_files",
+ $params);
}
-
cron_entry(25,$err);
?>
+++ /dev/null
-#! /usr/bin/perl -Tw
-
-use strict ;
-use vars qw/ $file $dirty_file $user $dirty_user $group $dirty_group
- $real_file $dirty_real_file $src_file $dest_dir $dest_file $retval
- $homedir_prefix $sys_dbpasswd / ;
-use subs qw/ &fileforge &tmpfilemove &wash_string / ;
-no locale ;
-
-# Clean up our environment
-delete @ENV{qw(IFS CDPATH ENV BASH_ENV PATH)};
-
-# Check access to secret
-require ("/usr/share/gforge/lib/include.pl") ;
-unless ( (defined $sys_dbpasswd)
- and (defined $ENV{'sys_dbpasswd'})
- and ($sys_dbpasswd eq $ENV{'sys_dbpasswd'}) ) {
- die "You are not authorized to run this script" ;
-}
-
-# Initialize a constant
-$homedir_prefix = "/var/lib/gforge/chroot/home/users/" ;
-
-# Check which mode we're in
-# Normal fileforge
-if ($0 eq "/usr/share/gforge/bin/fileforge.pl") {
- &fileforge ;
- exit 0 ;
-}
-# Temporary moving of files (for quick release system)
-if ($0 eq "/usr/share/gforge/bin/tmpfilemove.pl") {
- &tmpfilemove ;
- exit 0 ;
-}
-# If we're not in one of these two modes, then fail
-print STDERR "You must call this script as one of:
-* /usr/share/gforge/bin/fileforge.pl (normal execution)
-* /usr/share/gforge/bin/tmpfilemove.pl (for QRS)" ;
-die "Unauthorized invocation '$0'" ;
-
-sub fileforge {
- if ($#ARGV != 2) {
- die "Usage: fileforge.pl file user group" ;
- }
-
- # "Parse" command-line options
- $dirty_file = $ARGV [0] ;
- $dirty_user = $ARGV [1] ;
- $dirty_group = $ARGV [2] ;
-
- # Check and untaint $user and $file here
- $file = &wash_string ($dirty_file, "file", 1) ;
- $user = &wash_string ($dirty_user, "user", 0) ;
-
- # Compute source file name
- $src_file = $homedir_prefix ;
- $src_file .= $user ;
- $src_file .= "/incoming/" ;
- $src_file .= $file ;
-
- # Check and untaint $group here
- $group = &wash_string ($dirty_group, "group", 0) ;
-
- # Compute and test destination dir name
- $dest_dir = "/var/lib/gforge/download/" ;
- $dest_dir .= $group ;
- $dest_dir .= "/" ;
- unless ( -d $dest_dir ) {
- mkdir $dest_dir, 0755 or die $! ;
- chown 0, 0, $dest_dir or die $! ;
- }
- unless ( -d $dest_dir ) {
- die "Destination directory '$dest_dir' does not exist" ;
- }
-
- chmod 0400, $src_file ;
- chown 0, 0, $src_file ;
- chmod 0644, $src_file ;
- $retval = system "/bin/mv $src_file $dest_dir" ;
- if ($retval == -1) {
- die "Could not execute /bin/mv: $!" ;
- }
- if ($retval != 0) {
- die "Error moving file" ;
- }
-}
-
-sub tmpfilemove {
- if ($#ARGV != 2) {
- die "Usage: tmpfilemove.pl temp_filename real_filename user_unix_name" ;
- }
- $dirty_file = $ARGV [0] ;
- $dirty_real_file = $ARGV [1] ;
- $dirty_user = $ARGV [2] ;
-
- # Check and untaint variables here
- $file = &wash_string ($dirty_file, "file", 1) ;
- $real_file = &wash_string ($dirty_real_file, "real_file", 1) ;
- $user = &wash_string ($dirty_user, "user", 0) ;
-
- # Compute source file name
- $src_file = "/tmp/" ;
- $src_file .= $file ;
-
- # Insure the source file is good
- chmod 0400, $src_file ;
- $retval = system "/bin/chown $user:$user $src_file" ;
- if ($retval == -1) {
- die "Could not execute '/bin/chmod $user:$user $src_file': $!" ;
- }
- if ($retval != 0) {
- die "Error reattributing file" ;
- }
- chmod 0644, $src_file ;
-
- # Compute and test destination directory name
- $dest_dir = $homedir_prefix ;
- $dest_dir .= $user ;
- $dest_dir .= "/incoming/" ;
- unless ( -d $dest_dir ) {
- die "Destination directory '$dest_dir' does not exist" ;
- }
-
- # Compute destination file name
- $dest_file = $dest_dir . $real_file ;
-
- $retval = system "/bin/mv $src_file $dest_file" ;
- if ($retval == -1) {
- die "Could not execute /bin/mv: $!" ;
- }
- if ($retval != 0) {
- die "Error moving file" ;
- }
-}
-
-sub wash_string {
- my $string = shift ;
- my $name = shift ;
- my $allowtilde = shift ;
-
- # Empty strings are not allowed
- if (length $string == 0) {
- die "Forbidden empty $name '$string'" ;
- }
-
- if ($allowtilde) {
- # Only allowed characters are alphanumerical . + _ - ~
- if ($string =~ m,[^\w.+_~-],) {
- die "Forbidden characters in $name '$string'" ;
- }
- } else {
- # Only allowed characters are alphanumerical . + _ -
- if ($string =~ m,[^\w.+_-],) {
- die "Forbidden characters in $name '$string'" ;
- }
- }
-
- # No .. sequence is allowed
- if ($string =~ m,\.\.,) {
- die "Forbidden '..' sequence in $name 'string'" ;
- }
-
- my $clean = '' ;
-
- if ($string =~ /^([\w.+_-]+)$/) {
- $clean = $1 ;
- } else {
- die "Unexpected error while untainting $name '$string'" ;
- }
-
- return $clean ;
-}
# Begin functions
###############################################
+## Become this effective user (EUID/EGID) and perform this action.
+##
+## This protect against symlink attacks; they are inevitable when
+## working in a directory owned by a local user. We could naively
+## check for the presence of symlinks, but then we'd still be
+## vulnerable to a symlink race attack.
+##
+## We'll use set_e_uid/set_e_gid for efficiency and simplicity
+## (e.g. we can get the return value directly), which is enough for
+## opening files and similar basic operations. When calling external
+## programs, you should use fork&exec&setuid/setgid.
+##
+# arg1: username
+# arg2: a Perl sub{}
+sub SudoEffectiveUser {
+ my $user = $_[0];
+ my $sub_unprivileged = $_[1];
+
+ my ($uid,$gid) = GetUserUidGid($user);
+ if ($uid eq "" or $gid eq "") {
+ print "Unknown user: $user";
+ return;
+ }
+
+ my $old_GID = $GID; # save additional groups
+ $! = '';
+ $EGID = "$gid $gid"; # set egid and additional groups
+ if ($! ne '') {
+ warn "Cannot setegid($gid $gid): $!";
+ return;
+ }
+ $EUID = $uid;
+ if ($! ne '') {
+ warn "Cannot seteuid($uid): $!";
+ return;
+ }
+
+ # Perform the action under this effective user:
+ my $ret = &$sub_unprivileged();
+
+ # Back to root
+ undef($EUID); # restore euid==uid
+ $EGID = $old_GID; # restore egid==gid + additional groups
+
+ return $ret;
+}
+
+## Get system uid/gid
+sub GetUserUidGid {
+ my $user = $_[0];
+ my ($name,$passwd,$uid,$gid,
+ $quota,$comment,$gcos,$dir,$shell,$expire) = getpwnam($user);
+ return ($uid,$gid);
+}
+
#############################
# Group Add Function
#############################
if ($verbose) {print("Making a Group for : $gname\n")};
- mkdir $group_dir, $default_perms ;
- mkdir $log_dir, $default_perms ;
- mkdir $cgi_dir, $default_perms ;
- mkdir $ht_dir, $default_perms ;
- mkdir $inc_dir, $default_perms ;
- system("cp $default_page $ht_dir/index.php");
- # perl is sometime fucked to create with right permission
- system("chmod $default_perms $group_dir");
- system("chmod $default_perms $log_dir");
- system("chmod $default_perms $cgi_dir");
- system("chmod $default_perms $ht_dir");
- system("chmod $default_perms $inc_dir");
- system("chmod $file_default_perms $ht_dir/index.php");
- chown $dummy_uid, $gid, ($group_dir, $log_dir, $cgi_dir, $ht_dir);
- chown $dummy_uid, $gid, ("$ht_dir/index.php");
+ if (mkdir $group_dir, $default_perms) {
+ chown $dummy_uid, $gid, $group_dir ;
+
+ SudoEffectiveUser($dummy_uid, sub {
+ mkdir $log_dir, $default_perms ;
+ mkdir $cgi_dir, $default_perms ;
+ mkdir $ht_dir, $default_perms ;
+ mkdir $inc_dir, $default_perms ;
+ system("cp $default_page $ht_dir/index.php");
+ # perl is sometime fucked to create with right permission
+ chmod $default_perms, $group_dir;
+ chmod $default_perms, $log_dir;
+ chmod $default_perms, $cgi_dir;
+ chmod $default_perms, $ht_dir;
+ chmod $default_perms, $inc_dir;
+ chmod $file_default_perms, "$ht_dir/index.php";
+ });
+ }
}
#############################
if ($verbose) {print("Updating Group: $gname\n")};
- system("chmod $default_perms $group_dir");
- system("chmod $default_perms $log_dir");
- system("chmod $default_perms $cgi_dir");
- system("chmod $default_perms $ht_dir");
- system("chmod $default_perms $inc_dir");
- chown $dummy_uid, $gid, ($group_dir, $log_dir, $cgi_dir, $ht_dir, $inc_dir);
-
- my $realuid=get_file_owner_uid($group_dir);
- if ($dummy_uid eq $realuid){
- system("chown $dummy_uid $group_dir");
- } else {
- if($verbose){print("Changing owner of $group_dir $realuid -> $dummy_uid\n")};
- system("chown -R $dummy_uid $group_dir");
- }
- my $realgid=get_file_owner_gid($group_dir);
- if ($gid eq $realgid){
- system("chgrp $gid $group_dir");
- } else {
- if($verbose){print("Changing group of $group_dir $realgid -> $gid\n")};
- system("chgrp -R $gid $group_dir");
- }
+ chown $dummy_uid, $gid, $group_dir;
+
+ SudoEffectiveUser($dummy_uid, sub {
+ chmod $default_perms, $group_dir;
+ chmod $default_perms, $log_dir;
+ chmod $default_perms, $cgi_dir;
+ chmod $default_perms, $ht_dir;
+ chmod $default_perms, $inc_dir;
+ });
}
#############################
if($verbose){print ("Processing $username\n")};
if (-d "$homedir_prefix/$username"){
- if (! -d $ssh_dir) {
- mkdir $ssh_dir, 0755;
- chown $uid, $uid, $ssh_dir;
- }
-
- if($verbose){print("Writing authorized_keys for $username: ")};
+ chown $uid, $uid, ("$homedir_prefix/$username");
SudoEffectiveUser($username, sub {
+ if (! -d $ssh_dir) {
+ mkdir $ssh_dir, 0755;
+ }
+
+ if($verbose){print("Writing authorized_keys for $username: ")};
+
if (write_array_file("$ssh_dir/authorized_keys", @user_authorized_keys)) {
warn "Problem writing authorized_keys for $username\n";
next;
}
+ chmod 0644, "$ssh_dir/authorized_keys";
});
- chown $uid, $uid, ("$homedir_prefix/$username", $ssh_dir, "$ssh_dir/authorized_keys");
- chmod 0644, "$ssh_dir/authorized_keys";
-
if($verbose){print ("Done\n")};
} else {
if($verbose){print ("Not yet done, waiting for home creation\n")};
if (-d $ssh_dir) {
if($verbose){print("Resetting authorized_keys for $username: ")};
- if (-l "$ssh_dir") {
- warn("$ssh_dir is a symlink, possible symlink attack!");
- } else {
+ SudoEffectiveUser($username, sub {
unlink("$ssh_dir/authorized_keys");
- }
- system("chown $uid:$uid $homedir_prefix/$username");
- system("chown $uid:$uid $ssh_dir");
+ });
+
+ chown $uid, $uid, "$homedir_prefix/$username";
if($verbose){print ("Done\n")};
}
# Begin functions
###############################################
+## Become this effective user (EUID/EGID) and perform this action.
+##
+## This protect against symlink attacks; they are inevitable when
+## working in a directory owned by a local user. We could naively
+## check for the presence of symlinks, but then we'd still be
+## vulnerable to a symlink race attack.
+##
+## We'll use set_e_uid/set_e_gid for efficiency and simplicity
+## (e.g. we can get the return value directly), which is enough for
+## opening files and similar basic operations. When calling external
+## programs, you should use fork&exec&setuid/setgid.
+##
+# arg1: username
+# arg2: a Perl sub{}
+sub SudoEffectiveUser {
+ my $user = $_[0];
+ my $sub_unprivileged = $_[1];
+
+ my ($uid,$gid) = GetUserUidGid($user);
+ if ($uid eq "" or $gid eq "") {
+ print "Unknown user: $user";
+ return;
+ }
+
+ my $old_GID = $GID; # save additional groups
+ $! = '';
+ $EGID = "$gid $gid"; # set egid and additional groups
+ if ($! ne '') {
+ warn "Cannot setegid($gid $gid): $!";
+ return;
+ }
+ $EUID = $uid;
+ if ($! ne '') {
+ warn "Cannot seteuid($uid): $!";
+ return;
+ }
+
+ # Perform the action under this effective user:
+ my $ret = &$sub_unprivileged();
+
+ # Back to root
+ undef($EUID); # restore euid==uid
+ $EGID = $old_GID; # restore egid==gid + additional groups
+
+ return $ret;
+}
+
+## Get system uid/gid
+sub GetUserUidGid {
+ my $user = $_[0];
+ my ($name,$passwd,$uid,$gid,
+ $quota,$comment,$gcos,$dir,$shell,$expire) = getpwnam($user);
+ return ($uid,$gid);
+}
+
#############################
# Helper Function
#############################
mkdir $home_dir, 0755;
chown $uid, $gid, $home_dir;
- mkdir $home_dir.'/incoming', 0755;
- chown $uid, $gid, $home_dir.'/incoming' ;
+ SudoEffectiveUser($username, sub {
+ mkdir $home_dir.'/incoming', 0755;
+ });
}
#############################
if($verbose){print("Updating Account for: $username\n")};
- $home_dir = $homedir_prefix.'/'.$username;
- unless (-d $home_dir.'/incoming') {
- mkdir $home_dir.'/incoming', 0755;
- }
-
- my $realuid=get_file_owner_uid($home_dir);
- if ($uid eq $realuid){
- system("chown $uid $home_dir/incoming");
- system("chmod 0755 $home_dir/incoming");
- } else {
- if($verbose){print("Changing owner of $home_dir $realuid -> $uid\n")};
- system("chown -R $uid $home_dir");
- system("chmod 0755 $home_dir/incoming");
- }
- my $realgid=get_file_owner_gid($home_dir);
- if ($gid eq $realgid){
- system("chgrp $gid $home_dir/incoming");
- } else {
- if($verbose){print("Changing group of $home_dir $realgid -> $gid\n")};
- system("chgrp -R $gid $home_dir");
- }
+ SudoEffectiveUser($username, sub {
+ $home_dir = $homedir_prefix.'/'.$username;
+ if (-d $home_dir.'/incoming') {
+ chmod 0755, $home_dir.'/incoming';
+ } else {
+ mkdir $home_dir.'/incoming', 0755;
+ }
+ });
}
#############################
* Fail configuration of the -db-postgresql package if no database is
available, to prevent other packages from breaking things due to
misconfiguration.
+ * SECURITY: Avoid attacks with symbolic or hard links that could lead to
+ privilege escalation (CVE-2013-1423). Thanks to Helmut Grohne for the
+ initial report and help in preparing the fix.
[ Thorsten Glaser ]
* SECURITY: Upon user deletion, remove their Unix account as well
* SECURITY: Do not disclose inaccessible groups on user_home/toplist
- -- Roland Mas <lolando@debian.org> Fri, 21 Sep 2012 16:05:28 +0200
+ -- Roland Mas <lolando@debian.org> Tue, 19 Feb 2013 15:16:47 +0100
fusionforge (5.1.1-8) unstable; urgency=low
}
if (!$repo_exists) {
+ $tmp_repo = util_mkdtemp('.bzr', $project_name);
+ if ($tmp_repo == false) {
+ return false;
+ }
+
+ system ("bzr init-repo --no-trees $tmp_repo >/dev/null") ;
+ system ("find $tmp_repo/.bzr -type d | xargs chmod g+s") ;
+ system ("chmod -R g+wX,o+rX-w $tmp_repo/.bzr") ;
+ system ("chgrp $unix_group $tmp_repo/.bzr") ;
+
system ("mkdir -p $repo") ;
- system ("bzr init-repo --no-trees $repo >/dev/null") ;
- system ("find $repo -type d | xargs chmod g+s") ;
+ system ("chgrp $unix_group $repo") ;
+ system ("chmod g+s $repo") ;
+ system ("mv $tmp_repo/.bzr $repo/.bzr");
+ rmdir ($tmp_repo);
}
-
- system ("chgrp -R $unix_group $repo") ;
+
if ($project->enableAnonSCM()) {
- system ("chmod -R g+wX,o+rX-w $repo") ;
+ system ("chmod o+rX-w $repo") ;
} else {
- system ("chmod -R g+wX,o-rwx $repo") ;
+ system ("chmod o-rwx $repo") ;
}
}
}
if (!$repo_exists) {
- system ("cvs -d $repo init") ;
+ if (!mkdir($repo, 0700)) {
+ return false;
+ }
+ $ret = 0;
+ system ("cvs -d $repo init", $ret) ;
+ if ($ret != 0) {
+ return false;
+ }
system ("mkdir -p $locks_dir") ;
+ system ("chgrp $unix_group $locks_dir") ;
+ system ("chmod 3777 $locks_dir") ;
+
+ if (forge_get_config('use_shell')) {
+ $unix_group = 'scm_' . $project->getUnixName() ;
+
+ util_create_file_with_contents ("$repo/CVSROOT/config", "SystemAuth=no\nLockDir=$locks_dir\nUseNewInfoFmtStrings=yes\n");
+ if ($project->enableAnonSCM()) {
+ util_create_file_with_contents ("$repo/CVSROOT/readers", "anonymous\n");
+ util_create_file_with_contents ("$repo/CVSROOT/passwd", "anonymous:\n");
+ system ("chmod -R g+wXs,o+rX-w $repo") ;
+ } else {
+ util_create_file_with_contents ("$repo/CVSROOT/readers", "\n");
+ util_create_file_with_contents ("$repo/CVSROOT/passwd", "\n");
+ system ("chmod -R g+wXs,o-rwx $repo") ;
+ }
+ system ("chgrp -R $unix_group $repo") ;
+ } else {
+ $unix_user = forge_get_config ('apache_user') ;
+ $unix_group = forge_get_config ('apache_user') ;
+ system ("chmod -R g-rwx,o-rwx $repo") ;
+ system ("chown -R $unix_user:$unix_group $repo") ;
+ }
}
if (forge_get_config('use_shell')) {
- $unix_group = 'scm_' . $project->getUnixName() ;
-
- system ("chgrp -R $unix_group $repo $locks_dir") ;
- system ("chmod 3777 $locks_dir") ;
- system ("echo \"SystemAuth=no\" > $repo/CVSROOT/config");
- system ("echo \"LockDir=$locks_dir\" >> $repo/CVSROOT/config");
- system ("echo \"UseNewInfoFmtStrings=yes\" >> $repo/CVSROOT/config");
if ($project->enableAnonSCM()) {
- system ("chmod -R g+wXs,o+rX-w $repo") ;
- system ("echo \"anonymous\" > $repo/CVSROOT/readers");
- system ("echo \"anonymous:\" > $repo/CVSROOT/passwd");
+ util_create_file_with_contents ("$repo/CVSROOT/readers", "anonymous\n");
+ util_create_file_with_contents ("$repo/CVSROOT/passwd", "anonymous:\n");
+ system ("chmod g+wXs,o+rX-w $repo") ;
} else {
- system ("chmod -R g+wXs,o-rwx $repo") ;
- system ("echo \"\" > $repo/CVSROOT/readers");
- system ("echo \"\" > $repo/CVSROOT/passwd");
+ util_create_file_with_contents ("$repo/CVSROOT/readers", "\n");
+ util_create_file_with_contents ("$repo/CVSROOT/passwd", "\n");
+ system ("chmod g+wXs,o-rwx $repo") ;
}
- } else {
- $unix_user = forge_get_config ('apache_user') ;
- $unix_group = forge_get_config ('apache_user') ;
- system ("chown -R $unix_user:$unix_group $repo") ;
- system ("chmod -R g-rwx,o-rwx $repo") ;
}
}
if(!is_dir($cvsdir_prefix."/.deleted"))
system("mkdir ".$cvsdir_prefix."/.deleted");
- system("mv -f $cvsdir_prefix/$deleted_group_name/ $cvsdir_prefix/.deleted/");
- system("chown -R root:root $cvsdir_prefix/.deleted/$deleted_group_name");
- system("chmod -R o-rwx $cvsdir_prefix/.deleted/$deleted_group_name");
-
+ system("tar czfC $cvsdir_prefix/.deleted/$deleted_group_name.tar.gz $cvsdir_prefix $deleted_group_name");
+ system("chmod o-rwx $cvsdir_prefix/.deleted/$deleted_group_name.tar.gz");
+ system("rm -rf $cvsdir_prefix/$deleted_group_name");
$res9 = db_query_params ('UPDATE deleted_groups set isdeleted = 1 WHERE unix_group_name = $1',
array ($deleted_group_name));
'A',
'A'));
+function create_authkeys($params) {
+ $ssh_dir = $params['ssh_dir'];
+ $ssh_key = $params['ssh_key'];
+ if (!is_dir($ssh_dir)) {
+ mkdir ($ssh_dir, 0755);
+ }
+ $h8 = fopen("$ssh_dir/authorized_keys","w");
+ fwrite($h8,'# This file is automatically generated from your account settings.'."\n");
+ fwrite($h8,$ssh_key);
+ fclose($h8);
+ chmod ("$ssh_dir/authorized_keys", 0644);
+}
+
for ($i=0; $i<db_numrows($res); $i++) {
$err .= "Error! homedir_prefix/username Points To Root Directory!";
continue;
}
- $uid=db_result($res,$i,'user_id');
- $ssh_key=str_replace('###',"\n",$ssh_key);
- $uid += 1000;
-
- $ssh_dir = forge_get_config('homedir_prefix')."/$username/.ssh";
- if (!is_dir($ssh_dir)) {
- mkdir ($ssh_dir, 0755);
- }
-
- # Set the effective uid/gid to this user, so as to avoid symlink attacks
- $userinfo = posix_getpwnam($username);
- posix_setegid($userinfo['gid']);
- posix_seteuid($userinfo['uid']);
- $h8 = fopen("$ssh_dir/authorized_keys","w");
- fwrite($h8,'# This file is automatically generated from your account settings.'."\n");
- fwrite($h8,$ssh_key);
- fclose($h8);
- posix_seteuid(0);
- posix_setegid(0);
-
- system("chown $username:users ".forge_get_config('homedir_prefix')."/$username");
- system("chown $username:users $ssh_dir");
- system("chmod 0644 $ssh_dir/authorized_keys");
- system("chown $username:users $ssh_dir/authorized_keys");
+ $params = array();
+ $params['ssh_key'] = str_replace('###',"\n",$ssh_key);
+ $params['ssh_dir'] = forge_get_config('homedir_prefix')."/$username/.ssh";
+ util_sudo_effective_user($username, "create_authkeys", $params);
}
cron_entry(15,$err);
return ;
}
+ static function createUserRepo ($params) {
+ $project = $params['project'];
+ $project_name = $project->getUnixName();
+ $user_name = $params['user_name'];
+ $unix_group = $params['unix_group'];
+ $main_repo = $params['main_repo'];
+ $root = $params['root'];
+
+ $repodir = $root . '/users/' . $user_name . '.git' ;
+ chgrp ($repodir, $unix_group);
+ if ($project->enableAnonSCM()) {
+ chmod ($repodir, 02755);
+ } else {
+ chmod ($repodir, 02750);
+ }
+ if (!is_file ("$repodir/HEAD") && !is_dir("$repodir/objects") && !is_dir("$repodir/refs")) {
+ system ("git clone --bare $main_repo $repodir") ;
+ system ("GIT_DIR=\"$repodir\" git update-server-info") ;
+ if (is_file ("$repodir/hooks/post-update.sample")) {
+ rename ("$repodir/hooks/post-update.sample",
+ "$repodir/hooks/post-update") ;
+ }
+ if (!is_file ("$repodir/hooks/post-update")) {
+ $f = fopen ("$repodir/hooks/post-update","x+") ;
+ fwrite ($f, "exec git-update-server-info\n") ;
+ fclose ($f) ;
+ }
+ if (is_file ("$repodir/hooks/post-update")) {
+ system ("chmod +x $repodir/hooks/post-update") ;
+ }
+ system("echo \"Git repository for user $user_name in project $project_name\" > $repodir/description");
+ }
+ }
+
function createOrUpdateRepo ($params) {
$project = $this->checkParams ($params) ;
if (!$project) {
$main_repo = $root . '/' . $project_name . '.git' ;
if (!is_file ("$main_repo/HEAD") && !is_dir("$main_repo/objects") && !is_dir("$main_repo/refs")) {
- system ("GIT_DIR=\"$main_repo\" git init --bare --shared=group") ;
- system ("GIT_DIR=\"$main_repo\" git update-server-info") ;
- if (is_file ("$main_repo/hooks/post-update.sample")) {
- rename ("$main_repo/hooks/post-update.sample",
- "$main_repo/hooks/post-update") ;
+ $tmp_repo = util_mkdtemp('.git', $project_name);
+ if ($tmp_repo == false) {
+ return false;
}
- if (!is_file ("$main_repo/hooks/post-update")) {
- $f = fopen ("$main_repo/hooks/post-update") ;
+ system ("GIT_DIR=\"$tmp_repo\" git init --bare --shared=group") ;
+ system ("GIT_DIR=\"$tmp_repo\" git update-server-info") ;
+ if (is_file ("$tmp_repo/hooks/post-update.sample")) {
+ rename ("$tmp_repo/hooks/post-update.sample",
+ "$tmp_repo/hooks/post-update") ;
+ }
+ if (!is_file ("$tmp_repo/hooks/post-update")) {
+ $f = fopen ("$tmp_repo/hooks/post-update") ;
fwrite ($f, "exec git-update-server-info\n") ;
fclose ($f) ;
}
- if (is_file ("$main_repo/hooks/post-update")) {
- system ("chmod +x $main_repo/hooks/post-update") ;
+ if (is_file ("$tmp_repo/hooks/post-update")) {
+ system ("chmod +x $tmp_repo/hooks/post-update") ;
+ }
+ system ("echo \"Git repository for $project_name\" > $tmp_repo/description") ;
+ system ("find $tmp_repo -type d | xargs chmod g+s") ;
+ system ("chgrp -R $unix_group $tmp_repo") ;
+ if ($project->enableAnonSCM()) {
+ system ("chmod g+wX,o+rX-w $root") ;
+ system ("chmod -R g+wX,o+rX-w $tmp_repo") ;
+ } else {
+ system ("chmod g+wX,o-rwx $root") ;
+ system ("chmod -R g+wX,o-rwx $tmp_repo") ;
+ }
+ $ret = true;
+ system("mv $tmp_repo $main_repo", $ret);
+ if (!$ret) {
+ return false;
}
- system ("echo \"Git repository for $project_name\" > $main_repo/description") ;
- system ("find $main_repo -type d | xargs chmod g+s") ;
}
- system ("chgrp -R $unix_group $root") ;
+ system ("chgrp $unix_group $root") ;
system ("chmod g+s $root") ;
if ($project->enableAnonSCM()) {
system ("chmod g+wX,o+rX-w $root") ;
- system ("chmod -R g+wX,o+rX-w $main_repo") ;
+ system ("chmod g+wX,o+rX-w $main_repo") ;
} else {
system ("chmod g+wX,o-rwx $root") ;
- system ("chmod -R g+wX,o-rwx $main_repo") ;
+ system ("chmod g+wX,o-rwx $main_repo") ;
}
$result = db_query_params ('SELECT u.user_name FROM plugin_scmgit_personal_repos p, users u WHERE p.group_id=$1 AND u.user_id=p.user_id AND u.unix_status=$2',
system ("mkdir -p $root/users") ;
$user_name = db_result($result,$i,'user_name');
$repodir = $root . '/users/' . $user_name . '.git' ;
-
- if (!is_file ("$repodir/HEAD") && !is_dir("$repodir/objects") && !is_dir("$repodir/refs")) {
- system ("git clone --bare $main_repo $repodir") ;
- system ("GIT_DIR=\"$repodir\" git update-server-info") ;
- if (is_file ("$repodir/hooks/post-update.sample")) {
- rename ("$repodir/hooks/post-update.sample",
- "$repodir/hooks/post-update") ;
- }
- if (!is_file ("$repodir/hooks/post-update")) {
- $f = fopen ("$repodir/hooks/post-update") ;
- fwrite ($f, "exec git-update-server-info\n") ;
- fclose ($f) ;
- }
- if (is_file ("$repodir/hooks/post-update")) {
- system ("chmod +x $repodir/hooks/post-update") ;
- }
- system("echo \"Git repository for user $user_name in project $project_name\" > $repodir/description");
- system ("chown -R $user_name:$unix_group $repodir") ;
+
+ if (!is_dir($repodir) && mkdir ($repodir, 0700)) {
+ chown ($repodir, $user_name) ;
+
+ $params = array();
+ $params['project'] = $project;
+ $params['user_name'] = $user_name;
+ $params['unix_group'] = $unix_group;
+ $params['root'] = $root;
+ $params['main_repo'] = $main_repo;
+
+ util_sudo_effective_user($user_name,
+ array("GitPlugin","createUserRepo"),
+ $params);
}
}
if (is_dir ("$root/users")) {
if ($project->enableAnonSCM()) {
- system ("chmod -R g+rX-w,o+rX-w $root/users") ;
+ system ("chmod g+rX-w,o+rX-w $root/users") ;
} else {
- system ("chmod -R g+rX-w,o-rwx $root/users") ;
+ system ("chmod g+rX-w,o-rwx $root/users") ;
}
}
}
$repo = forge_get_config('repos_path', 'scmsvn') . '/' . $project->getUnixName() ;
if (!is_dir ($repo) || !is_file ("$repo/format")) {
- system ("svnadmin create $repo") ;
+ if (!mkdir($repo, 0700)) {
+ return false;
+ }
+ $ret = 0;
+ system ("svnadmin create $repo", $ret) ;
+ if ($ret != 0) {
+ return false;
+ }
+ if (forge_get_config('use_ssh', 'scmsvn')) {
+ $unix_group = 'scm_' . $project->getUnixName() ;
+ system ("find $repo -type d | xargs -I{} chmod g+s {}") ;
+ if ($project->enableAnonSCM()) {
+ system ("chmod -R g+wX,o+rX-w $repo") ;
+ } else {
+ system ("chmod -R g+wX,o-rwx $repo") ;
+ }
+ system ("chgrp -R $unix_group $repo") ;
+ } else {
+ $unix_user = forge_get_config('apache_user');
+ $unix_group = forge_get_config('apache_group');
+ system ("chmod -R g-rwx,o-rwx $repo") ;
+ system ("chown -R $unix_user:$unix_group $repo") ;
+ }
system ("svn mkdir -m'Init' file:///$repo/trunk file:///$repo/tags file:///$repo/branches >/dev/null") ;
}
$this->installOrUpdateCmds($project, $project->getUnixName(), $repo);
if (forge_get_config('use_ssh', 'scmsvn')) {
- $unix_group = 'scm_' . $project->getUnixName() ;
- system ("find $repo -type d | xargs -I{} chmod g+s {}") ;
- system ("chgrp -R $unix_group $repo") ;
if ($project->enableAnonSCM()) {
- system ("chmod -R g+wX,o+rX-w $repo") ;
+ system ("chmod g+wX,o+rX-w $repo") ;
} else {
- system ("chmod -R g+wX,o-rwx $repo") ;
+ system ("chmod g+wX,o-rwx $repo") ;
}
} else {
$unix_user = forge_get_config('apache_user');
$unix_group = forge_get_config('apache_group');
- system ("chown -R $unix_user:$unix_group $repo") ;
- system ("chmod -R g-rwx,o-rwx $repo") ;
+ system ("chown $unix_user:$unix_group $repo") ;
+ system ("chmod g-rwx,o-rwx $repo") ;
}
}
if (!is_dir($groups_dir))
system("mkdir -p $groups_dir");
+function populate_initial_wiki($params) {
+ $template_groups = $params['template_groups'];
+ $name = $params['name'];
+ $groups_dir = $params['groups_dir'];
+
+ if (isset($template_groups) && !empty($template_groups))
+ system("(cd $basedir/$template_groups ; tar cf - --exclude=.svn *) |" .
+ " (cd $groups_dir/$name; tar xf -)");
+}
+$userinfo = posix_getpwnam($file_owner);
while ( $row = db_fetch_array($res) ) {
if ($first_letter) {
$name = $row["unix_group_name"][0]."/".$row["unix_group_name"];
if (!is_dir("$groups_dir/$name")) {
system("mkdir -p $groups_dir/$name");
-
- if (isset($template_groups) && !empty($template_groups))
- system("(cd $basedir/$template_groups ; tar cf - --exclude=.svn *) |" .
- " (cd $groups_dir/$name; tar xf -)");
+ system("chown $file_owner $groups_dir/$name");
+
+ $params = array();
+ $params['template_groups'] = $template_groups;
+ $params['name'] = $name;
+ $params['groups_dir'] = $groups_dir;
+
+ util_sudo_effective_user($file_owner,
+ "populate_initial_wiki",
+ $params);
}
}
-system("chown $file_owner -R $groups_dir/.");
-system("find $groups_dir/. -type d -exec chmod 700 {} \;");
-system("find $groups_dir/. -type f -exec chmod 600 {} \;");
+util_sudo_effective_user($file_owner,
+ function() use ($groups_dir) {
+ system("find $groups_dir -type d -exec chmod 700 {} \;");
+ system("find $groups_dir -type f -exec chmod 600 {} \;");
+ });
cron_entry(901,$err);
?>
+++ /dev/null
-#!/bin/sh
-echo ""
-echo "CVS Repository Tool"
-echo "(c)1999 SourceForge Development Team"
-echo "Released under the GPL, 1999"
-echo ""
-
-# if no arguments, print out help screen
-if test $# -lt 2; then
- echo "usage:"
- echo " cvscreate.sh [repositoryname] [groupid]"
- echo ""
- exit 1
-fi
-
-# make sure this repository doesn't already exist
-if [ -d /cvsroot/$1 ] ; then
- echo "$1 already exists."
- echo ""
- exit 1
-fi
-
-# first create the repository
-mkdir /cvsroot/$1
-cvs -d/cvsroot/$1 init
-
-# make it group writable
-chmod 775 /cvsroot/$1
-
-# import default directory, with default cvs.txt
-#mkdir $1
-#cp cvs.txt $1
-#cd $1
-#cvs -d/cvsroot/$1 import -m "SourceForge CVStool creation" $1 SourceForge start
-#rm cvs.txt
-#cd ..
-#rmdir $1
-
-# turn off pserver writers, on anonymous readers
-echo "" > /cvsroot/$1/CVSROOT/writers
-echo "anonymous" > /cvsroot/$1/CVSROOT/readers
-echo "anonymous:\$1\$0H\$2/LSjjwDfsSA0gaDYY5Df/:anoncvs_$1" > /cvsroot/$1/CVSROOT/passwd
-
-# setup loginfo to make group ownership every commit
-echo "ALL chgrp -R $1 /cvsroot/$1" > /cvsroot/$1/CVSROOT/loginfo
-echo "" > /cvsroot/$1/CVSROOT/val-tags
-chmod 664 /cvsroot/$1/CVSROOT/val-tags
-
-# set group ownership, anonymous group user
-chown -R nobody:$2 /cvsroot/$1
-cat /etc/passwd | grep -v anoncvs_$1 > newpasswd
-cp newpasswd /etc/passwd
-rm -f newpasswd
-/usr/sbin/adduser -M -g $2 -d/cvsroot/$1 -s /bin/false -n anoncvs_$1
-
#############################
sub write_array_file {
my ($file_name, @file_array) = @_;
+ my $oldmask = umask(077);
use File::Temp qw(tempfile);
use File::Basename qw(dirname);
my ($fd, $filename) = tempfile( DIR => dirname($file_name), UNLINK => 0) ;
+ umask($oldmask);
+
return 1 unless ($fd && $filename) ;
foreach (@file_array) {