From 753ce75b151c2d2fd5f3e0911e805550c858f218 Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Wed, 5 Nov 2014 20:27:52 +0000 Subject: [PATCH] using univention-directory-manager cli to create not accounts to get Kerberos stuff addded --- doc/rpm-build/post_install.php | 2 +- .../inc/class.accounts_univention.inc.php | 82 +++++++++++++++++++ setup/inc/class.setup_cmd_config.inc.php | 49 ++++++++++- setup/inc/hook_config.inc.php | 11 +++ setup/templates/default/config.tpl | 4 +- 5 files changed, 140 insertions(+), 8 deletions(-) create mode 100644 phpgwapi/inc/class.accounts_univention.inc.php diff --git a/doc/rpm-build/post_install.php b/doc/rpm-build/post_install.php index 6872b81a41..739e52083b 100755 --- a/doc/rpm-build/post_install.php +++ b/doc/rpm-build/post_install.php @@ -766,7 +766,7 @@ function set_univention_defaults() $config['account_min_id'] = 1200; // UCS use 11xx for internal users/groups - $config['account-auth'] = 'ldap'; + $config['account-auth'] = 'univention,ldap'; // set sambaadmin sambaSID $config['sambaadmin/sambaSID'] = exec('/usr/bin/univention-ldapsearch -x "(objectclass=sambadomain)" sambaSID|sed -n "s/sambaSID: \(.*\)/\1/p"'); diff --git a/phpgwapi/inc/class.accounts_univention.inc.php b/phpgwapi/inc/class.accounts_univention.inc.php new file mode 100644 index 0000000000..bfafc8a426 --- /dev/null +++ b/phpgwapi/inc/class.accounts_univention.inc.php @@ -0,0 +1,82 @@ + + * + * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License + * @package api + * @subpackage accounts + * @version $Id$ + */ + +/** + * Univention LDAP Backend for accounts + * + * This backend is mostly identical to LDAP backend and need to be configured in the same way. + * Only difference is that new users get created via univention-directory-manager CLI program, + * to generate necesary Kerberos stuff. + */ +class accounts_univention extends accounts_ldap +{ + /** + * Name of binary to call + */ + const DIRECTORY_MANAGER_BIN = '/usr/sbin/univention-directory-manager'; + + /** + * Saves / adds the data of one account + * + * If no account_id is set in data the account is added and the new id is set in $data. + * + * @param array $data array with account-data + * @return int|boolean the account_id or false on error + */ + function save(&$data) + { + if (!$data['account_id'] && $data['account_type'] !== 'g' && self::available()) + { + $params = array( + 'users/user','create', + '--binddn', $this->frontend->config['ldap_root_dn'], + '--bindpwd', 5=>$this->frontend->config['ldap_root_pw'], + '--position', $this->frontend->config['ldap_context'], + '--set', 'username='.$data['account_lid'], + '--set', 'firstname='.$data['account_firstname'], + '--set', 'lastname='.$data['account_lastname'], + ); + if ($data['account_email']) + { + $params[] = '--set'; $params[] = 'mailPrimaryAddress='.$data['account_email']; + } + if (!empty($data['account_passwd'])) + { + $params[] = '--set'; $params[] = 'password='.$data['account_passwd']; + } + $cmd = self::DIRECTORY_MANAGER_BIN.' '.implode(' ', array_map('escapeshellarg', $params)); + $output_arr = $ret = $matches = null; + exec($cmd, $output_arr, $ret); + $output = explode("\n", $output_arr); + if ($ret || !preg_match('/^Object created: (uid=.*)$/mui', $output, $matches)) + { + $params[5] = '********'; // mask out password! + $cmd = self::DIRECTORY_MANAGER_BIN.' '.implode(' ', array_map('escapeshellarg', $params)); + throw new egw_exception_wrong_userinput($cmd."\nreturned\n".$output); + } + $data['account_dn'] = $matches[1]; + $data['account_id'] = $this->name2id($matches[1], 'account_dn', 'u'); + } + return parent::save($data); + } + + /** + * Check if our function depending on an external binary is available + * + * @return boolean + */ + public static function available() + { + return file_exists(self::DIRECTORY_MANAGER_BIN) && is_executable(self::DIRECTORY_MANAGER_BIN); + } +} diff --git a/setup/inc/class.setup_cmd_config.inc.php b/setup/inc/class.setup_cmd_config.inc.php index 26383250d2..6cfc89d613 100644 --- a/setup/inc/class.setup_cmd_config.inc.php +++ b/setup/inc/class.setup_cmd_config.inc.php @@ -82,10 +82,15 @@ class setup_cmd_config extends setup_cmd { if (substr($name, 0, 4) == 'acc_') continue; + $app = 'phpgwapi'; + if (strpos($name, '/') !== false) + { + list($app, $name) = explode('/', $name); + } self::$egw_setup->db->insert(self::$egw_setup->config_table,array( 'config_value' => $value, ),array( - 'config_app' => 'phpgwapi', + 'config_app' => $app, 'config_name' => $name, ),__LINE__,__FILE__); } @@ -194,6 +199,7 @@ class setup_cmd_config extends setup_cmd '--ldap-context' => 'ldap_context', '--ldap-search-filter' => 'ldap_search_filter', '--ldap-group-context' => 'ldap_group_context', + '--sambaadmin-sid' => 'sambaadmin/sambaSID', '--allow-remote-admin' => 'allow_remote_admin', '--install-id' => 'install_id', '--ads-host' => 'ads_host', @@ -397,10 +403,14 @@ class setup_cmd_config extends setup_cmd { if (is_array($data) && isset($data['allowed'])) { - if ($data['name'] == 'auth_type') + switch ($data['name']) { - $options[$data['name']] = self::auth_types(); - continue; + case 'auth_type': + $options[$data['name']] = self::auth_types(); + continue 2; + case 'account_repository': + $options[$data['name']] = self::account_repositries(); + continue 2; } foreach($data['allowed'] as $label => $value) { @@ -460,6 +470,37 @@ class setup_cmd_config extends setup_cmd return $auth_types; } + /** + * Read auth-types (existing auth backends) from filesystem and fix our $options array + * + * @return array + */ + static function account_repositories() + { + static $account_repositories = array( + 'sql' => 'SQL', + 'ldap' => 'LDAP', + 'ads' => 'Active Directory', + ); + static $scan_done = null; + if (!$scan_done++) + { + // now add auth backends found in filesystem + foreach(scandir(EGW_INCLUDE_ROOT.'/phpgwapi/inc') as $file) + { + $matches = null; + if (preg_match('/^class\.accounts_([a-z]+)\.inc\.php$/', $file, $matches) && + !isset($account_repositories[$matches[1]]) && + class_exists($class='accounts_'.$matches[1]) && + (!is_callable($callable=$class.'::available') || call_user_func($callable))) + { + $account_repositories[$matches[1]] = ucfirst($matches[1]); + } + } + } + return $account_repositories; + } + /** * Return the defaults from the $options array * diff --git a/setup/inc/hook_config.inc.php b/setup/inc/hook_config.inc.php index 6bc2912a04..0779a36d69 100644 --- a/setup/inc/hook_config.inc.php +++ b/setup/inc/hook_config.inc.php @@ -185,6 +185,17 @@ function auth_type_activesync($config) return _options_from(setup_cmd_config::auth_types(),$config['auth_type_activesync']); } +/** + * Make account-repository-types from setup_cmd_config available + * + * @param array $config + * @return string + */ +function account_repository($config) +{ + return _options_from(setup_cmd_config::account_repositories(), $config['account_repository']); +} + /** * Returns options string * diff --git a/setup/templates/default/config.tpl b/setup/templates/default/config.tpl index 389349ce96..65723c6abd 100644 --- a/setup/templates/default/config.tpl +++ b/setup/templates/default/config.tpl @@ -173,9 +173,7 @@ {lang_Select_where_you_want_to_store/retrieve_user_accounts}: