mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-25 01:13:25 +01:00
* Setup/LDAP/ADS: script to change uidNumber and gidNumber in LDAP to match relative id (last part of SID) in preparation of Samba4 migration and using ActiveDirectory
This commit is contained in:
parent
0cd63aefc2
commit
014a273908
95
setup/doc/chown.php
Executable file
95
setup/doc/chown.php
Executable file
@ -0,0 +1,95 @@
|
||||
#!/usr/bin/php
|
||||
<?php
|
||||
/**
|
||||
* EGroupware setup - test or create the ldap connection and hierarchy
|
||||
*
|
||||
* @link http://www.egroupware.org
|
||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @package setup
|
||||
* @copyright (c) 2013 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
chdir(dirname(__FILE__)); // to enable our relative pathes to work
|
||||
|
||||
if (isset($_SERVER['HTTP_HOST'])) // security precaution: forbit calling as web-page
|
||||
{
|
||||
die('<h1>setup/doc/chown.php must NOT be called as web-page --> exiting !!!</h1>');
|
||||
}
|
||||
|
||||
$recursive = false;
|
||||
|
||||
$cmd = array_shift($_SERVER['argv']);
|
||||
|
||||
if ($_SERVER['argv'] && in_array($_SERVER['argv'][0], array('-R', '--recursive')))
|
||||
{
|
||||
$recursive = true;
|
||||
array_shift($_SERVER['argv']);
|
||||
}
|
||||
|
||||
if (count($_SERVER['argv']) != 2)
|
||||
{
|
||||
usage();
|
||||
}
|
||||
|
||||
function usage()
|
||||
{
|
||||
die("\nUsage: $cmd [-R|--recursive] from-id,to-id[,from-id2,to-id2,...] path\n\nonly nummeric ids are allowed, group-ids have to be negative!\n\n");
|
||||
}
|
||||
$ids = explode(',', $_SERVER['argv'][0]);
|
||||
$change = array();
|
||||
while($ids)
|
||||
{
|
||||
$from = (int)array_shift($ids);
|
||||
$to = (int)array_shift($ids);
|
||||
|
||||
if (!$from || !$to || ($from < 0) != ($to < 0))
|
||||
{
|
||||
echo "from-id and to-id must be nummeric and have same sign (negative for groups)!\n\n";
|
||||
usage();
|
||||
}
|
||||
$change[$from] = $to;
|
||||
}
|
||||
|
||||
$path = $_SERVER['argv'][1];
|
||||
if (!file_exists($path))
|
||||
{
|
||||
echo "File or directory '$path' not found!\n\n";
|
||||
usage();
|
||||
}
|
||||
|
||||
if (posix_getuid())
|
||||
{
|
||||
die("\nNeed to run as root, to be able to change owner and group!\n\n");
|
||||
}
|
||||
|
||||
chown_grp($path, null, $recursive);
|
||||
|
||||
function chown_grp($path, array $stat=null, $recursive=false)
|
||||
{
|
||||
global $change;
|
||||
|
||||
if (is_null($stat) && !($stat = stat($path))) return false;
|
||||
|
||||
if (isset($change[$stat['uid']]) && !chown($path, $uid=$change[$stat['uid']]))
|
||||
{
|
||||
echo "Faild to set new owner #$uid for $path\n";
|
||||
}
|
||||
if (isset($change[-$stat['gid']]) && !chgrp($path, $gid=-$change[-$stat['gid']]))
|
||||
{
|
||||
echo "Faild to set new group #$gid for $path\n";
|
||||
}
|
||||
|
||||
if ($recursive && is_dir($path))
|
||||
{
|
||||
foreach(new DirectoryIterator($path) as $child)
|
||||
{
|
||||
if (!$child->isDot())
|
||||
chown_grp($child->getPathname(), array(
|
||||
'uid' => $child->getOwner(),
|
||||
'gid' => $child->getGroup(),
|
||||
), $recursive);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,11 +1,11 @@
|
||||
<?php
|
||||
/**
|
||||
* eGgroupWare setup - test or create the ldap connection and hierarchy
|
||||
* EGroupware setup - test or create the ldap connection and hierarchy
|
||||
*
|
||||
* @link http://www.egroupware.org
|
||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @package setup
|
||||
* @copyright (c) 2007-10 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @copyright (c) 2007-13 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @version $Id$
|
||||
*/
|
||||
@ -15,8 +15,17 @@
|
||||
*
|
||||
* All commands can be run via setup-cli eg:
|
||||
*
|
||||
* setup/setup-cli.php --setup_cmd_ldap stylite.de,config-user,config-pw sub_command=set_mailbox \
|
||||
* ldap_base=dc=local ldap_admin=cn=admin,dc=local ldap_admin_pw=secret ldap_host=localhost test=1
|
||||
* setup/setup-cli.php [--dry-run] --setup_cmd_ldap <domain>,<config-user>,<config-pw> sub_command=set_mailbox \
|
||||
* ldap_base=dc=local ldap_root_dn=cn=admin,dc=local ldap_root_pw=secret ldap_host=localhost
|
||||
*
|
||||
* Changing uid/gidNumber to match SID in preparation to Samba4 migration:
|
||||
*
|
||||
* setup/setup-cli.php [--dry-run] --setup_cmd_ldap <domain>,<config-user>,<config-pw> sub_command=sid2uidnumber \
|
||||
* ldap_base=dc=local ldap_root_dn=cn=admin,dc=local ldap_root_pw=secret ldap_host=localhost
|
||||
*
|
||||
* - First run it with --dry-run to get ids to change / admin-cli command to change ids in EGroupware.
|
||||
* - Then run admin/admin-cli.php --change-account-id and after this command again without --dry-run.
|
||||
* - After that you need to run the given setup/doc/chown.php command to change filesystem uid/gid in samba share.
|
||||
*/
|
||||
class setup_cmd_ldap extends setup_cmd
|
||||
{
|
||||
@ -91,8 +100,10 @@ class setup_cmd_ldap extends setup_cmd
|
||||
{
|
||||
throw new egw_exception_wrong_userinput(lang("'%1' is no valid domain name!",$this->domain));
|
||||
}
|
||||
if ($this->remote_id && $check_only) return true; // further checks can only done locally
|
||||
|
||||
if ($this->remote_id && $check_only && !in_array($this->sub_command, array('set_mailbox', 'sid2uidnumber')))
|
||||
{
|
||||
return true; // further checks can only done locally
|
||||
}
|
||||
$this->_merge_defaults();
|
||||
//_debug_array($this->as_array());
|
||||
|
||||
@ -115,7 +126,10 @@ class setup_cmd_ldap extends setup_cmd
|
||||
$msg = $this->migrate($this->sub_command == 'migrate_to_ldap');
|
||||
break;
|
||||
case 'set_mailbox':
|
||||
$msg = $this->set_mailbox();
|
||||
$msg = $this->set_mailbox($check_only);
|
||||
break;
|
||||
case 'sid2uidnumber':
|
||||
$msg = $this->sid2uidnumber($check_only);
|
||||
break;
|
||||
case 'create_ldap':
|
||||
default:
|
||||
@ -125,6 +139,97 @@ class setup_cmd_ldap extends setup_cmd
|
||||
return $msg;
|
||||
}
|
||||
|
||||
const sambaSID = 'sambasid';
|
||||
|
||||
/**
|
||||
* Change uidNumber and gidNumber to match rid (last part of sambaSID)
|
||||
*
|
||||
* First run it with --dry-run to get ids to change / admin-cli command to change ids in EGroupware.
|
||||
* Then run admin/admin-cli.php --change-account-id and after this command again without --dry-run.
|
||||
* After that you need to run the given chown.php command to change filesystem uid/gid in samba share.
|
||||
*
|
||||
* @param boolean $check_only=false true: only connect and output necessary commands
|
||||
*/
|
||||
private function sid2uidnumber($check_only=false)
|
||||
{
|
||||
$msg = array();
|
||||
$this->connect();
|
||||
|
||||
// check if base does exist
|
||||
if (!@ldap_read($this->test_ldap->ds,$this->ldap_base,'objectClass=*'))
|
||||
{
|
||||
throw new egw_exception_wrong_userinput(lang('Base dn "%1" NOT found!',$this->ldap_base));
|
||||
}
|
||||
|
||||
if (!($sr = ldap_search($this->test_ldap->ds,$this->ldap_base,
|
||||
'(&(|(objectClass=posixAccount)(objectClass=posixGroup))('.$search=self::sambaSID.'=*)(!(gecos=*)))',
|
||||
array('uidNumber','gidNumber','uid','cn', 'objectClass',self::sambaSID))) ||
|
||||
!($entries = ldap_get_entries($this->test_ldap->ds, $sr)))
|
||||
{
|
||||
throw new egw_exception(lang('Error searching "dn=%1" for "%2"!',$this->ldap_base, $search));
|
||||
}
|
||||
$change = $accounts = array();
|
||||
$cmd_change_account_id = 'admin/admin-cli.php --change-account-id <admin>@<domain>,<adminpw>';
|
||||
$change_account_id = '';
|
||||
foreach($entries as $key => $entry)
|
||||
{
|
||||
if ($key === 'count') continue;
|
||||
|
||||
$entry = self::ldap2array($entry);
|
||||
$accounts[$entry['dn']] = $entry;
|
||||
//print_r($entry);
|
||||
|
||||
$parts = explode('-', $entry[self::sambaSID]);
|
||||
$rid = array_pop($parts);
|
||||
|
||||
if (in_array('posixAccount', $entry['objectclass']))
|
||||
{
|
||||
$id = $entry['uidnumber'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$id = -$entry['gidnumber'];
|
||||
$rid *= -1;
|
||||
}
|
||||
if ($id != $rid)
|
||||
{
|
||||
$change[$id] = $rid;
|
||||
$change_account_id .= ','.$id.','.$rid;
|
||||
}
|
||||
}
|
||||
//print_r($change); die('Stop');
|
||||
|
||||
// change account-ids inside EGroupware
|
||||
if ($check_only) $msg[] = "You need to run now:\n$cmd_change_account_id $change_account_id";
|
||||
//$cmd = new admin_cmd_change_account_id($change);
|
||||
//$msg[] = $cmd->run($time=null, $set_modifier=false, $skip_checks=false, $check_only);
|
||||
|
||||
// now change them in LDAP
|
||||
$changed = 0;
|
||||
foreach($accounts as $dn => $account)
|
||||
{
|
||||
$modify = array();
|
||||
if (!empty($account['uidnumber']) && isset($change[$account['uidnumber']]))
|
||||
{
|
||||
$modify['uidnumber'] = $change[$account['uidnumber']];
|
||||
}
|
||||
if (isset($change[-$account['gidnumber']]))
|
||||
{
|
||||
$modify['gidnumber'] = -$change[-$account['gidnumber']];
|
||||
}
|
||||
if (!$check_only && $modify && !ldap_modify($this->test_ldap->ds, $dn, $modify))
|
||||
{
|
||||
throw new egw_exception("Failed to modify ldap: !ldap_modify({$this->test_ldap->ds}, '$dn', ".array2string($modify).") ".ldap_error($this->test_ldap->ds).
|
||||
"\n- ".implode("\n- ", $msg)); // EGroupware change already run successful
|
||||
}
|
||||
if ($modify) ++$changed;
|
||||
}
|
||||
$msg[] = "You need to run now on your samba share(s):\nsetup/doc/chown.php -R $change_account_id <share>";
|
||||
|
||||
return ($check_only ? 'Need to update' : 'Updated')." $changed entries with new uid/gidNumber in LDAP".
|
||||
"\n- ".implode("\n- ", $msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate to other account storage
|
||||
*
|
||||
@ -383,6 +488,35 @@ class setup_cmd_ldap extends setup_cmd
|
||||
return $hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a single ldap value into a associative array
|
||||
*
|
||||
* @param array $ldap array with numerical and associative indexes and count's
|
||||
* @return array with only associative index and no count's
|
||||
*/
|
||||
public static function ldap2array($ldap)
|
||||
{
|
||||
if (!is_array($ldap)) return false;
|
||||
|
||||
$arr = array();
|
||||
foreach($ldap as $var => $val)
|
||||
{
|
||||
if (is_int($var) || $var === 'count') continue;
|
||||
|
||||
if (is_array($val) && $val['count'] == 1)
|
||||
{
|
||||
$arr[$var] = $val[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_array($val)) unset($val['count']);
|
||||
|
||||
$arr[$var] = $val;
|
||||
}
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read all accounts from sql or ldap
|
||||
*
|
||||
@ -602,7 +736,7 @@ class setup_cmd_ldap extends setup_cmd
|
||||
* @return string with success message N entries modified
|
||||
* @throws egw_exception if dn not found, not listable or delete fails
|
||||
*/
|
||||
private function set_mailbox()
|
||||
private function set_mailbox($check_only=false)
|
||||
{
|
||||
$this->connect($this->ldap_admin,$this->ldap_admin_pw);
|
||||
|
||||
@ -639,16 +773,16 @@ class setup_cmd_ldap extends setup_cmd
|
||||
|
||||
if ($mbox === $entry[$mbox_attr][0]) continue; // nothing to change
|
||||
|
||||
if (!$this->test && !ldap_modify($this->test_ldap->ds,$entry['dn'],array(
|
||||
if (!$check_only && !ldap_modify($this->test_ldap->ds,$entry['dn'],array(
|
||||
$mbox_attr => $mbox,
|
||||
)))
|
||||
{
|
||||
throw new egw_exception(lang("Error modifying dn=%1: %2='%3'!",$dn,$mbox_attr,$mbox));
|
||||
}
|
||||
++$modified;
|
||||
if ($this->test) echo "$modified: $entry[dn]: $mbox_attr={$entry[$mbox_attr][0]} --> $mbox\n";
|
||||
if ($check_only) echo "$modified: $entry[dn]: $mbox_attr={$entry[$mbox_attr][0]} --> $mbox\n";
|
||||
}
|
||||
return $this->test ? lang('%1 entries would have been modified.',$modified) :
|
||||
return $check_only ? lang('%1 entries would have been modified.',$modified) :
|
||||
lang('%1 entries modified.',$modified);
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
* @link http://www.egroupware.org
|
||||
* @package setup
|
||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @copyright (c) 2006-9 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @copyright (c) 2006-13 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @version $Id$
|
||||
*/
|
||||
@ -17,10 +17,17 @@ if (isset($_SERVER['HTTP_HOST'])) // security precaution: forbit calling setup-c
|
||||
{
|
||||
die('<h1>setup-cli.php must NOT be called as web-page --> exiting !!!</h1>');
|
||||
}
|
||||
elseif ($_SERVER['argc'] > 1)
|
||||
$dry_run = false;
|
||||
array_shift($_SERVER['argv']);
|
||||
|
||||
if ($_SERVER['argv'])
|
||||
{
|
||||
if ($_SERVER['argv'][0] == '--dry-run')
|
||||
{
|
||||
$dry_run = true;
|
||||
array_shift($_SERVER['argv']);
|
||||
}
|
||||
$arguments = $_SERVER['argv'];
|
||||
array_shift($arguments);
|
||||
$action = array_shift($arguments);
|
||||
if (isset($arguments[0])) list($_POST['FormDomain']) = explode(',',$arguments[0]); // header include needs that to detects the right domain
|
||||
}
|
||||
@ -52,7 +59,7 @@ $GLOBALS['egw_setup']->system_charset = $charset;
|
||||
|
||||
if ((float) PHP_VERSION < $GLOBALS['egw_setup']->required_php_version)
|
||||
{
|
||||
throw new egw_exception_wrong_userinput(lang('You are using PHP version %1. eGroupWare now requires %2 or later, recommended is PHP %3.',PHP_VERSION,$GLOBALS['egw_setup']->required_php_version,$GLOBALS['egw_setup']->recommended_php_version),98);
|
||||
throw new egw_exception_wrong_userinput(lang('You are using PHP version %1. EGroupware now requires %2 or later, recommended is PHP %3.',PHP_VERSION,$GLOBALS['egw_setup']->required_php_version,$GLOBALS['egw_setup']->recommended_php_version),98);
|
||||
}
|
||||
|
||||
switch($action)
|
||||
@ -136,7 +143,7 @@ switch($action)
|
||||
}
|
||||
}
|
||||
$cmd = new $class($args);
|
||||
$msg = $cmd->run();
|
||||
$msg = $cmd->run($time=null, $set_modifier=true, $skip_checks=false, $check_only=$dry_run);
|
||||
if (is_array($msg)) $msg = print_r($msg,true);
|
||||
echo "$msg\n";
|
||||
break;
|
||||
@ -146,7 +153,7 @@ switch($action)
|
||||
exit(0);
|
||||
|
||||
/**
|
||||
* Configure eGroupWare
|
||||
* Configure EGroupware
|
||||
*
|
||||
* @param array $args domain(default),[config user(admin)],password,[,name=value,...] --files-dir --backup-dir --mailserver
|
||||
*/
|
||||
@ -351,7 +358,7 @@ function _check_auth_config($arg,$stop,$set_lang=true)
|
||||
}
|
||||
|
||||
/**
|
||||
* Install eGroupWare
|
||||
* Install EGroupware
|
||||
*
|
||||
* @param array $args array(0 => "domain,[config user(admin)],password,[backup-file],[charset],[lang]", "name=value", ...)
|
||||
*/
|
||||
@ -461,7 +468,7 @@ function do_usage($what='')
|
||||
|
||||
if (!$what)
|
||||
{
|
||||
echo '--check '.lang('checks eGroupWare\'s installed, it\'s versions and necessary upgrads (return values see --exit-codes)')."\n";
|
||||
echo '--check '.lang('checks EGroupware\'s installed, it\'s versions and necessary upgrads (return values see --exit-codes)')."\n";
|
||||
echo '--install '.lang('domain(default),[config user(admin)],password,[backup to install],[charset(default depends on language)]')."\n";
|
||||
}
|
||||
if (!$what || $what == 'config')
|
||||
@ -491,7 +498,7 @@ function do_usage($what='')
|
||||
}
|
||||
if (!$what || $what == 'header')
|
||||
{
|
||||
echo lang('Create or edit the eGroupWare configuration file: header.inc.php:')."\n";
|
||||
echo lang('Create or edit the EGroupware configuration file: header.inc.php:')."\n";
|
||||
echo '--create-header '.lang('header-password[,header-user(admin)]')."\n";
|
||||
echo '--edit-header '.lang('[header-password],[header-user],[new-password],[new-user]')."\n";
|
||||
if (!$what) echo ' --help header '.lang('gives further options')."\n";
|
||||
@ -499,14 +506,14 @@ function do_usage($what='')
|
||||
if ($what == 'header')
|
||||
{
|
||||
echo "\n".lang('Additional options and there defaults (in brackets)')."\n";
|
||||
echo '--server-root '.lang('path of eGroupWare install directory (default auto-detected)')."\n";
|
||||
echo '--server-root '.lang('path of EGroupware install directory (default auto-detected)')."\n";
|
||||
echo '--session-type '.lang('{db | php(default) | php-restore}')."\n";
|
||||
echo '--limit-access '.lang('comma separated ip-addresses or host-names, default access to setup from everywhere')."\n";
|
||||
echo '--mcrypt '.lang('use mcrypt to crypt session-data: {off(default) | on},[mcrypt-init-vector(default randomly generated)],[mcrypt-version]')."\n";
|
||||
echo '--db-persistent '.lang('use persistent db connections: {on(default) | off}')."\n";
|
||||
echo '--domain-selectbox '.lang('{off(default) | on}')."\n";
|
||||
|
||||
echo "\n".lang('Adding, editing or deleting an eGroupWare domain / database instance:')."\n";
|
||||
echo "\n".lang('Adding, editing or deleting an EGroupware domain / database instance:')."\n";
|
||||
echo '--domain '.lang('add or edit a domain: [domain-name(default)],[db-name(egroupware)],[db-user(egroupware)],db-password,[db-type(mysql)],[db-host(localhost)],[db-port(db specific)],[config-user(as header)],[config-passwd(as header)]')."\n";
|
||||
echo '--delete-domain '.lang('domain-name')."\n";
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user