return $text;
}
+function util_is_html($string) {
+ return (strip_tags(util_unconvert_htmlspecialchars($string)) != $string);
+}
+
+function util_init_messages() {
+ global $feedback, $warning_msg, $error_msg;
+
+ if (PHP_SAPI == 'cli') {
+ $feedback = $warning_msg = $error_msg = '';
+ } else {
+ $feedback = getStringFromCookie('feedback', '');
+ if ($feedback) setcookie('feedback', '', time()-3600, '/');
+
+ $warning_msg = getStringFromCookie('warning_msg', '');
+ if ($warning_msg) setcookie('warning_msg', '', time()-3600, '/');
+
+ $error_msg = getStringFromCookie('error_msg', '');
+ if ($error_msg) setcookie('error_msg', '', time()-3600, '/');
+ }
+}
+
+function util_save_messages() {
+ global $feedback, $warning_msg, $error_msg;
+
+ setcookie('feedback', $feedback, time() + 10, '/');
+ setcookie('warning_msg', $warning_msg, time() + 10, '/');
+ setcookie('error_msg', $error_msg, time() + 10, '/');
+}
+
+ /**
+ * 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
// c-file-style: "bsd"
//test if the FTP upload dir exists and create it if not
if (!is_dir(forge_get_config('ftp_upload_dir'))) {
- @mkdir(forge_get_config('ftp_upload_dir'),0755,true);
+ @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() ;
+ $groupname = $project->getUnixName();
//create an FTP upload dir for this project
if (forge_get_config('use_ftp_uploads')) {
if (!is_dir(forge_get_config('ftp_upload_dir').'/'.$groupname)) {
}
}
- if (is_dir(forge_get_config('groupdir_prefix')."/".$groupname)) {
-
- } else {
+ if (!is_dir(forge_get_config('groupdir_prefix')."/".$groupname)) {
@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);
- }
-
- if (forge_get_config('use_manual_uploads')) {
- $incoming = forge_get_config('groupdir_prefix').'/'.$groupname.'/incoming';
- if (!is_dir($incoming)) {
- @mkdir($incoming);
- }
+ system("chown ".forge_get_config('apache_user').":".forge_get_config('apache_group')." ".forge_get_config('groupdir_prefix')."/".$groupname);
}
- 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);
require $gfcommon.'include/cron_utils.php';
$err='';
- $res1 = db_query_params('select userid, user_name from sshkeys, users
- where sshkeys.userid = users.user_id
- and users.status = $1
- and users.unix_status = $2',
- array('A', 'A'));
- for ($i = 0; $i < db_numrows($res1); $i++) {
- $userid = db_result($res1, $i, 'userid');
- $username = db_result($res1, $i, 'user_name');
- $res2 = db_query_params('select sshkey from sshkeys, users
-$res=db_query_params ('SELECT user_name,user_id,authorized_keys
- FROM users
- WHERE authorized_keys != $1
- AND status=$2 AND unix_status = $3',
- array('',
- 'A',
- 'A'));
++$res2 = db_query_params('SELECT sshkey, user_name from sshkeys, users
+ where sshkeys.userid = users.user_id
+ and users.status = $1
+ and users.unix_status = $2
+ and sshkeys.deleted = $3
- and sshkeys.deploy = $4
- and sshkeys.userid = $5',
- array('A', 'A', 0, 0, $userid));
- $ssh_key = '';
- while ($arr = db_fetch_array($res2)) {
- $ssh_key .= $arr['sshkey']."\n";
++ and sshkeys.deploy = $4',
++ array('A', 'A', 0, 0));
++$keys = array();
++while ($arr = db_fetch_array($res2)) {
++ $username = $arr['user_name'];
++ $key = $arr['sshkey'];
++ if (!exists($keys[$username])) {
++ $keys[$username] = array();
+ }
-
++ $keys[$username][] = $key;
++}
+
+ 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++) {
-
++foreach ($keys as $username => $v) {
++ $ssh_key = join("\n", $v);
+
- $ssh_key=db_result($res,$i,'authorized_keys');
- $username=db_result($res,$i,'user_name');
$dir = forge_get_config('homedir_prefix').'/'.$username;
if (util_is_root_dir($dir)) {
- $err .= "Error! homedir_prefix/username Points To Root Directory!";
+ $err .= "Error! homedir_prefix/username Points To Root Directory!";
continue;
}
- $uid = $userid;
- $uid += 1000;
-
- $ssh_dir = $dir.'/.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);
- chown($dir, $username);
- chgrp($dir, 'users');
- chown($ssh_dir, $username);
- chgrp($ssh_dir, 'users');
- chmod($ssh_dir.'/authorized_keys', 0644);
- chown($ssh_dir.'/authorized_keys', $username);
- chgrp($ssh_dir.'/authorized_keys', 'users');
+ $params = array();
+ $params['ssh_key'] = str_replace('###',"\n",$ssh_key);
+ $params['ssh_dir'] = forge_get_config('homedir_prefix')."/$username/.ssh";
- db_query_params('update sshkeys set deploy = $1 where userid = $2 and deploy = $3',
- array(1, $userid, 0));
- db_query_params('delete from sshkeys where userid = $1 and deleted = $2',
- array($userid, 1));
+ util_sudo_effective_user($username, "create_authkeys", $params);
}
cron_entry(15,$err);
}
$project_name = $project->getUnixName();
- $root = forge_get_config('repos_path', 'scmgit') . '/' . $project_name ;
- system ("mkdir -p $root");
+ $root = forge_get_config('repos_path', 'scmgit') . '/' . $project_name;
+ if (!is_dir($root)) {
+ system("mkdir -p $root");
+ }
$output = '';
+ if (forge_get_config('use_ssh','scmgit')) {
+ $unix_group = 'scm_' . $project_name ;
+ } else {
+ $unix_group = forge_get_config('apache_group');
+ }
+
+ // Create main repository
$main_repo = $root . '/' . $project_name . '.git' ;
- if (!is_file("$main_repo/HEAD") && !is_dir("$main_repo/objects") && !is_dir("$main_repo/refs")) {
- exec("GIT_DIR=\"$main_repo\" git init --bare --shared=group", $result) ;
+ if (!is_file ("$main_repo/HEAD") && !is_dir("$main_repo/objects") && !is_dir("$main_repo/refs")) {
+ $tmp_repo = util_mkdtemp('.git', $project_name);
+ if ($tmp_repo == false) {
+ return false;
+ }
- $result = system ("GIT_DIR=\"$tmp_repo\" git init --bare --shared=group") ;
- $output .= join("<br />", array($result));
- $result = system ("GIT_DIR=\"$tmp_repo\" git update-server-info") ;
- $output .= join("<br />", array($result));
++ $result = '';
++ exec ("GIT_DIR=\"$tmp_repo\" git init --bare --shared=group", $result) ;
+ $output .= join("<br />", $result);
+ $result = '';
- exec("GIT_DIR=\"$main_repo\" git update-server-info", $result) ;
++ exec ("GIT_DIR=\"$tmp_repo\" git update-server-info", $result) ;
+ $output .= join("<br />", $result);
- if (is_file("$main_repo/hooks/post-update.sample")) {
- rename("$main_repo/hooks/post-update.sample",
- "$main_repo/hooks/post-update");
+ if (is_file ("$tmp_repo/hooks/post-update.sample")) {
+ rename ("$tmp_repo/hooks/post-update.sample",
+ "$tmp_repo/hooks/post-update") ;
}
- if (!is_file("$main_repo/hooks/post-update")) {
- $f = fopen("$main_repo/hooks/post-update", 'w');
- fwrite($f, "exec git-update-server-info\n");
- fclose($f);
+ if (!is_file ("$tmp_repo/hooks/post-update")) {
- $f = fopen ("$tmp_repo/hooks/post-update") ;
++ $f = fopen ("$tmp_repo/hooks/post-update", 'w') ;
+ 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") ;
}
if (forge_get_config('use_ssh','scmgit')) {
- $unix_group = 'scm_' . $project_name ;
- system ("chgrp -R $unix_group $root") ;
- system ("chmod g+s $root") ;
if ($project->enableAnonSCM()) {
system ("chmod g+wX,o+rX-w $root") ;
- system ("chmod -R g+rwX,o+rX-w $main_repo") ;
+ system ("chmod g+rwX,o+rX-w $main_repo") ;
} else {
system ("chmod g+wX,o-rwx $root") ;
- system ("chmod -R g+rwX,o-rwx $main_repo") ;
+ system ("chmod g+rwX,o-rwx $main_repo") ;
}
} else {
$unix_user = forge_get_config('apache_user');
- $unix_group = forge_get_config('apache_group');
- system ("chown -R $unix_user:$unix_group $main_repo") ;
- system ("chmod -R g-rwx,o-rwx $main_repo") ;
+ system ("chown $unix_user:$unix_group $main_repo") ;
+ system ("chmod g-rwx,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',
+ // Create project-wide secondary repositories
+ $result = db_query_params ('SELECT repo_name, description, clone_url FROM scm_secondary_repos WHERE group_id=$1 AND next_action = $2 AND plugin_id=$3',
+ array ($project->getID(),
+ SCM_EXTRA_REPO_ACTION_UPDATE,
+ $this->getID()));
+ $rows = db_numrows ($result) ;
+ for ($i=0; $i<$rows; $i++) {
+ $repo_name = db_result($result,$i,'repo_name');
+ $description = db_result($result,$i,'description');
+ $clone_url = db_result($result,$i,'clone_url');
+ $repodir = $root . '/' . $repo_name . '.git' ;
+ if (!is_file ("$repodir/HEAD") && !is_dir("$repodir/objects") && !is_dir("$repodir/refs")) {
+ if ($clone_url != '') {
+ system ("cd $root;git clone --bare $clone_url $repodir") ;
+ } else {
+ system ("GIT_DIR=\"$repodir\" git init --bare --shared=group") ;
+ }
+ 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") ;
+ }
+ $f = fopen("$repodir/description", "w");
+ fwrite($f, $description."\n");
+ fclose($f);
+ system ("chgrp -R $unix_group $repodir") ;
+ system ("chmod g+s $root") ;
+ if ($project->enableAnonSCM()) {
+ system ("chmod -R g+wX,o+rX-w $main_repo") ;
+ } else {
+ system ("chmod -R g+wX,o-rwx $main_repo") ;
+ }
+ }
+ }
+
+ // Delete project-wide secondary repositories
+ $result = db_query_params ('SELECT repo_name FROM scm_secondary_repos WHERE group_id=$1 AND next_action = $2 AND plugin_id=$3',
array ($project->getID(),
- 'A')) ;
+ SCM_EXTRA_REPO_ACTION_DELETE,
+ $this->getID()));
+ $rows = db_numrows ($result) ;
+ for ($i=0; $i<$rows; $i++) {
+ $repo_name = db_result($result,$i,'repo_name');
+ $repodir = $root . '/' . $repo_name . '.git' ;
+ if (util_is_valid_repository_name($repo_name)) {
+ system ("rm -rf $repodir");
+ }
+ db_query_params ('DELETE FROM scm_secondary_repos WHERE group_id=$1 AND repo_name=$2 AND next_action = $3 AND plugin_id=$4',
+ array ($project->getID(),
+ $repo_name,
+ SCM_EXTRA_REPO_ACTION_DELETE,
+ $this->getID()));
+ }
+
+ // Create users' personal repositories
+ $result = db_query_params ('SELECT u.user_name FROM scm_personal_repos p, users u WHERE p.group_id=$1 AND u.user_id=p.user_id AND u.unix_status=$2 AND plugin_id=$3',
+ array ($project->getID(),
+ 'A',
+ $this->getID()));
$rows = db_numrows ($result) ;
for ($i=0; $i<$rows; $i++) {
system ("mkdir -p $root/users") ;
ssh root@$HOST "(echo [core];echo use_ssl=no) > /etc/gforge/config.ini.d/zzz-buildbot.ini"
ssh root@$HOST "(echo [moinmoin];echo use_frame=no) >> /etc/gforge/config.ini.d/zzz-buildbot.ini"
ssh root@$HOST "(echo [mediawiki];echo unbreak_frames=yes) >> /etc/gforge/config.ini.d/zzz-buildbot.ini"
- ssh root@$HOST "service nscd stop"
+ssh root@$HOST "[ -e /var/lib/gforge/.bazaar/bazaar.conf ] && sed -i -e s,https://,http://,g /var/lib/gforge/.bazaar/bazaar.conf"
+ ssh root@$HOST "service nscd restart"
# Dump database
echo "Dump freshly installed database"