An error occurred while loading the file. Please try again.
-
Côme Chilliet authored
There are some left in datepicker.js because of a bug in the sniffer, I did not find a way to fix that yet. issue #5690
e985f071
<?php
/*
This code is part of FusionDirectory (http://www.fusiondirectory.org/)
Copyright (C) 2007 Fabian Hickert
Copyright (C) 2011-2015 FusionDirectory
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/****************
* FUNCTIONS
Step_Migrate - Constructor.
update_strings - Used to update the displayed step informations.
initialize_checks - Initialize migration steps.
check_ldap_permissions - Check if the used admin account has full access to the ldap database.
check_gosaAccounts - Check if there are users without the required objectClasses.
migrate_gosaAccounts - Migrate selected users to FusionDirectory user accounts.
check_organizationalUnits - Check if there are departments, that are not visible for FusionDirectory
migrate_organizationalUnits - Migrate selected departments
check_administrativeAccount - Check if there is at least one acl entry available
checkBase - Check if there is a root object available
get_user_list - Get list of available users
create_admin
create_admin_user
execute - Generate html output of this plugin
save_object - Save posts
array_to_ldif - Create ldif output of an ldap result array
****************/
class Step_Migrate extends setup_step
{
var $languages = array();
var $attributes = array('valid_admin');
var $header_image = 'geticon.php?context=applications&icon=utilities-system-monitor&size=48';
var $checks = array();
/* Department migration attributes */
var $dep_migration_dialog = FALSE;
var $deps_to_migrate = array();
var $show_details = FALSE;
/* Department migration attributes */
var $users_migration_dialog = FALSE;
var $users_to_migrate = array();
/* Create Acl attributes */
var $acl_create_dialog = FALSE;
var $acl_create_selected = ""; // Currently selected element, that should receive admin rights
var $acl_create_changes = ""; // Contains ldif information about changes
var $acl_create_confirmed = FALSE;
/* Checks initialised ? */
var $checks_initialised = FALSE;
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
/* Users outside to people ou */
var $outside_users = array();
var $outside_users_dialog = FALSE;
/* Users outside to groups ou */
var $outside_groups = array();
var $outside_groups_dialog = FALSE;
/* Device migration */
var $device_dialog = FALSE;
var $device = array();
/* Service migration */
var $service_dialog = FALSE;
var $service = array();
/* Group menus */
var $menu_dialog = FALSE;
var $menu = array();
/* check for multiple use of same uidNumber */
var $check_uidNumbers = array();
var $check_uidNumbers_dialog = FALSE;
/* check for multiple use of same gidNumber */
var $check_gidNumbers = array();
var $check_gidNumbers_dialog = FALSE;
var $group_list = array();
/* Migrable users */
var $migrate_users = array();
var $acl_migrate_dialog = FALSE;
var $migrate_acl_base_entry = "";
/* Root object classes */
var $rootOC_migrate_dialog = FALSE;
var $rootOC_details = array();
/* One valid admin dn */
var $valid_admin = FALSE;
/* Defaults ACL roles */
var $defaultRoles;
function __construct()
{
$this->update_strings();
$this->fill_defaultRoles();
}
function update_strings()
{
$this->s_title = _("LDAP inspection");
$this->s_title_long = _("LDAP inspection");
$this->s_info = _("Analyze your current LDAP for FusionDirectory compatibility");
}
function fill_defaultRoles()
{
$this->defaultRoles = array(
array(
'cn' => 'manager',
'description' => _('Give all rights on users in the given branch'),
'objectclass' => array('top', 'gosaRole'),
'gosaAclTemplate' => '0:user/password;cmdrw,user/user;cmdrw,user/posixAccount;cmdrw'
),
array(
'cn' => 'editowninfos',
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
'description' => _('Allow users to edit their own information (main tab and posix use only on base)'),
'objectclass' => array('top', 'gosaRole'),
'gosaAclTemplate' => '0:user/posixAccount;srw,user/user;srw'
),
array(
'cn' => 'editowninfos',
'description' => _('Allow users to edit their own password (use only on base)'),
'objectclass' => array('top', 'gosaRole'),
'gosaAclTemplate' => '0:user/password;srw'
),
);
}
function initialize_checks()
{
$this->checks = array();
$this->checks['root']['TITLE'] = _("Checking for root object");
$this->checks['root']['STATUS'] = FALSE;
$this->checks['root']['STATUS_MSG'] = "";
$this->checks['root']['ERROR_MSG'] = "";
$this->checkBase();
$this->checks['rootOC']['TITLE'] = _("Inspecting object classes in root object");
$this->checks['rootOC']['STATUS'] = FALSE;
$this->checks['rootOC']['STATUS_MSG'] = "";
$this->checks['rootOC']['ERROR_MSG'] = "";
$this->checkBaseOC();
$this->checks['permissions']['TITLE'] = _("Checking permission for LDAP database");
$this->checks['permissions']['STATUS'] = FALSE;
$this->checks['permissions']['STATUS_MSG'] = "";
$this->checks['permissions']['ERROR_MSG'] = "";
$this->check_ldap_permissions();
$this->checks['deps_visible']['TITLE'] = _("Checking for invisible departments");
$this->checks['deps_visible']['STATUS'] = FALSE;
$this->checks['deps_visible']['STATUS_MSG'] = "";
$this->checks['deps_visible']['ERROR_MSG'] = "";
$this->checks['users_visible']['TITLE'] = _("Checking for invisible users");
$this->checks['users_visible']['STATUS'] = FALSE;
$this->checks['users_visible']['STATUS_MSG'] = "";
$this->checks['users_visible']['ERROR_MSG'] = "";
$this->check_gosaAccounts();
$this->migrate_users = array();
$this->checks['acls']['TITLE'] = _("Checking for super administrator");
$this->checks['acls']['STATUS'] = FALSE;
$this->checks['acls']['STATUS_MSG'] = "";
$this->checks['acls']['ERROR_MSG'] = "";
$this->check_administrativeAccount();
$this->checks['default_acls']['TITLE'] = _("Checking for default ACL roles and groupes");
$this->checks['default_acls']['STATUS'] = FALSE;
$this->checks['default_acls']['STATUS_MSG'] = "";
$this->checks['default_acls']['ERROR_MSG'] = "";
$this->check_defaultACLs();
$this->checks['outside_users']['TITLE'] = _("Checking for users outside the people tree");
$this->checks['outside_users']['STATUS'] = FALSE;
$this->checks['outside_users']['STATUS_MSG'] = "";
$this->checks['outside_users']['ERROR_MSG'] = "";
$this->search_outside_users();
$this->checks['outside_groups']['TITLE'] = _("Checking for groups outside the groups tree");
$this->checks['outside_groups']['STATUS'] = FALSE;
$this->checks['outside_groups']['STATUS_MSG'] = "";
$this->checks['outside_groups']['ERROR_MSG'] = "";
$this->search_outside_groups();
$this->check_organizationalUnits();
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
$this->checks['uidNumber_usage']['TITLE'] = _("Checking for duplicated user ids");
$this->checks['uidNumber_usage']['STATUS'] = FALSE;
$this->checks['uidNumber_usage']['STATUS_MSG'] = "";
$this->checks['uidNumber_usage']['ERROR_MSG'] = "";
$this->check_uidNumber();
$this->checks['gidNumber_usage']['TITLE'] = _("Checking for duplicate group ids");
$this->checks['gidNumber_usage']['STATUS'] = FALSE;
$this->checks['gidNumber_usage']['STATUS_MSG'] = "";
$this->checks['gidNumber_usage']['ERROR_MSG'] = "";
$this->check_gidNumber();
$this->checks['old_style_devices']['TITLE'] = _("Checking for old style USB devices");
$this->checks['old_style_devices']['STATUS'] = FALSE;
$this->checks['old_style_devices']['STATUS_MSG'] = "";
$this->checks['old_style_devices']['ERROR_MSG'] = "";
$this->check_usb_devices();
$this->checks['old_style_services']['TITLE'] = _("Checking for old services that have to be migrated");
$this->checks['old_style_services']['STATUS'] = FALSE;
$this->checks['old_style_services']['STATUS_MSG'] = "";
$this->checks['old_style_services']['ERROR_MSG'] = "";
$this->check_services();
$this->checks['old_style_menus']['TITLE'] = _("Checking for old style application menus");
$this->checks['old_style_menus']['STATUS'] = FALSE;
$this->checks['old_style_menus']['STATUS_MSG'] = "";
$this->checks['old_style_menus']['ERROR_MSG'] = "";
$this->check_menus();
}
/* Check if there are uidNumbers which are used more than once */
function check_uidNumber()
{
global $config;
$ldap = $config->get_ldap_link();
$ldap->cd($config->current['BASE']);
$res = $ldap->search("(&(objectClass=posixAccount)(uidNumber=*))", array("dn","uidNumber"));
if (!$res) {
$this->checks['uidNumber_usage']['STATUS'] = FALSE;
$this->checks['uidNumber_usage']['STATUS_MSG'] = _("LDAP query failed");
$this->checks['uidNumber_usage']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
return FALSE;
}
$this->check_uidNumbers = array();
$tmp = array();
while ($attrs = $ldap->fetch()) {
$tmp[$attrs['uidNumber'][0]][] = $attrs;
}
foreach ($tmp as $entries) {
if (count($entries) > 1) {
foreach ($entries as $entry) {
$this->check_uidNumbers[base64_encode($entry['dn'])] = $entry;
}
}
}
if ($this->check_uidNumbers) {
$this->checks['uidNumber_usage']['STATUS'] = FALSE;
$this->checks['uidNumber_usage']['STATUS_MSG'] = "<div style='color:#F0A500'>"._("Warning")."</div>";
$this->checks['uidNumber_usage']['ERROR_MSG'] =
sprintf(_("Found %s duplicate values for attribute 'uidNumber'."), count($this->check_uidNumbers));
return FALSE;
} else {
$this->checks['uidNumber_usage']['STATUS'] = TRUE;
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
$this->checks['uidNumber_usage']['STATUS_MSG'] = _("Ok");
$this->checks['uidNumber_usage']['ERROR_MSG'] = "";
return TRUE;
}
}
/* Check if there are duplicated gidNumbers present in ldap */
function check_gidNumber()
{
global $config;
$ldap = $config->get_ldap_link();
$ldap->cd($config->current['BASE']);
$res = $ldap->search("(&(objectClass=posixGroup)(gidNumber=*))", array("dn","gidNumber"));
if (!$res) {
$this->checks['gidNumber_usage']['STATUS'] = FALSE;
$this->checks['gidNumber_usage']['STATUS_MSG'] = _("LDAP query failed");
$this->checks['gidNumber_usage']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
return FALSE;
}
$this->check_gidNumbers = array();
$tmp = array();
while ($attrs = $ldap->fetch()) {
$tmp[$attrs['gidNumber'][0]][] = $attrs;
}
foreach ($tmp as $entries) {
if (count($entries) > 1) {
foreach ($entries as $entry) {
$this->check_gidNumbers[base64_encode($entry['dn'])] = $entry;
}
}
}
if ($this->check_gidNumbers) {
$this->checks['gidNumber_usage']['STATUS'] = FALSE;
$this->checks['gidNumber_usage']['STATUS_MSG'] = "<div style='color:#F0A500'>"._("Warning")."</div>";
$this->checks['gidNumber_usage']['ERROR_MSG'] =
sprintf(_("Found %s duplicate values for attribute 'gidNumber'."), count($this->check_gidNumbers));
return FALSE;
} else {
$this->checks['gidNumber_usage']['STATUS'] = TRUE;
$this->checks['gidNumber_usage']['STATUS_MSG'] = _("Ok");
$this->checks['gidNumber_usage']['ERROR_MSG'] = "";
return TRUE;
}
}
/* Search for groups outside the group ou */
function search_outside_groups()
{
global $config;
$ldap = $config->get_ldap_link();
$group_ou = get_ou('groupRDN');
$ldap->cd($config->current['BASE']);
/***********
* Get all gosaDepartments to be able to
* validate correct ldap tree position of every single user
***********/
$valid_deps = array();
$valid_deps['/'] = $config->current['BASE'];
$ldap->search("(&(objectClass=gosaDepartment)(ou=*))", array("dn","ou"));
while ($attrs = $ldap->fetch()) {
$valid_deps[] = $attrs['dn'];
}
351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
/***********
* Get all groups
***********/
$res = $ldap->search("(objectClass=posixGroup)", array("dn"));
if (!$res) {
$this->checks['outside_groups']['STATUS'] = FALSE;
$this->checks['outside_groups']['STATUS_MSG'] = _("LDAP query failed");
$this->checks['outside_groups']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
return FALSE;
}
$this->outside_groups = array();
$this->groups_list = array();;
while ($attrs = $ldap->fetch()) {
$group_db_base = preg_replace("/^[^,]+,".preg_quote($group_ou, '/')."+/i", "", $attrs['dn']);
/* Check if entry is not an addressbook only user
* and verify that he is in a valid department
*/
if ( !preg_match("/".preg_quote("dc=addressbook,", '/')."/", $group_db_base) &&
!in_array($group_db_base, $valid_deps)
) {
$attrs['selected'] = FALSE;
$attrs['ldif'] = "";
$this->outside_groups[base64_encode($attrs['dn'])] = $attrs;
}
$this->group_list[] = $attrs['dn'];
}
if (count($this->outside_groups)) {
$this->checks['outside_groups']['STATUS'] = FALSE;
$this->checks['outside_groups']['STATUS_MSG'] = "<div style='color:#F0A500'>"._("Warning")."</div>";
$this->checks['outside_groups']['ERROR_MSG'] =
sprintf(_("Found %s groups outside the configured tree '%s'."), count($this->outside_groups), $group_ou);
$this->checks['outside_groups']['ERROR_MSG'] .= " <input type='submit' name='outside_groups_dialog' value='"._("Move")."...'>";
return FALSE;
} else {
$this->checks['outside_groups']['STATUS'] = TRUE;
$this->checks['outside_groups']['STATUS_MSG'] = _("Ok");
$this->checks['outside_groups']['ERROR_MSG'] = "";
return TRUE;
}
}
/* Search for users outside the people ou */
function search_outside_users()
{
global $config;
$ldap = $config->get_ldap_link();
$ldap->cd($config->current['BASE']);
/***********
* Get all gosaDepartments to be able to
* validate correct ldap tree position of every single user
***********/
$valid_deps = array();
$valid_deps['/'] = $config->current['BASE'];
$ldap->search("(&(objectClass=gosaDepartment)(ou=*))", array("dn","ou"));
while ($attrs = $ldap->fetch()) {
$valid_deps[] = $attrs['dn'];
}
/***********
* Search for all users
***********/
$res = $ldap->search("(&(objectClass=gosaAccount)(!(uid=*$)))", array("dn"));
if (!$res) {
$this->checks['outside_users']['STATUS'] = FALSE;
$this->checks['outside_users']['STATUS_MSG'] = _("LDAP query failed");
421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
$this->checks['outside_users']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
return FALSE;
}
/***********
* Check if returned users are within a valid GOsa department. (peopleou,gosaDepartment,base)
***********/
$this->outside_users = array();
$people_ou = trim(get_ou('userRDN'));
while ($attrs = $ldap->fetch()) {
$people_db_base = preg_replace("/^[^,]+,".preg_quote($people_ou, '/')."/i", "", $attrs['dn']);
/* Check if entry is not an addressbook only user
* and verify that he is in a valid department
*/
if ( !preg_match("/dc=addressbook,/", $people_db_base) &&
!in_array($people_db_base, $valid_deps)
) {
$attrs['selected'] = FALSE;
$attrs['ldif'] = "";
$this->outside_users[base64_encode($attrs['dn'])] = $attrs;
}
}
if (count($this->outside_users)) {
$this->checks['outside_users']['STATUS'] = FALSE;
$this->checks['outside_users']['STATUS_MSG'] = "<div style='color:#F0A500'>"._("Warning")."</div>";
$this->checks['outside_users']['ERROR_MSG'] =
sprintf(_("Found %s user(s) outside the configured tree '%s'."), count($this->outside_users), $people_ou);
$this->checks['outside_users']['ERROR_MSG'] .= "<input type='submit' name='outside_users_dialog' value='"._("Move")."...'>";
return FALSE;
} else {
$this->checks['outside_users']['STATUS'] = TRUE;
$this->checks['outside_users']['STATUS_MSG'] = _("Ok");
$this->checks['outside_users']['ERROR_MSG'] = "";
return TRUE;
}
}
/* Check ldap accessibility
* Create and remove a dummy object,
* to ensure that we have the necessary permissions
*/
function check_ldap_permissions()
{
global $config;
$ldap = $config->get_ldap_link();
/* Create dummy entry */
$name = "GOsa_setup_text_entry_".session_id().rand(0, 999999);
$dn = "ou=".$name.",".$config->current['BASE'];
$testEntry = array();
$testEntry['objectClass'][] = "top";
$testEntry['objectClass'][] = "organizationalUnit";
$testEntry['objectClass'][] = "gosaDepartment";
$testEntry['description'] = "Created by FusionDirectory setup, this object can be removed.";
$testEntry['ou'] = $name;
/* check if simple ldap cat will be successful */
$res = $ldap->cat($config->current['BASE']);
if (!$res) {
$this->checks['permissions']['STATUS'] = FALSE;
$this->checks['permissions']['STATUS_MSG'] = _("LDAP query failed");
$this->checks['permissions']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
return FALSE;
}
491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
/* Try to create dummy object */
$ldap->cd ($dn);
$res = $ldap->add($testEntry);
$ldap->cat($dn);
if (!$ldap->count()) {
new log("view", "setup/".get_class($this), $dn, array(), $ldap->get_error());
$this->checks['permissions']['STATUS'] = FALSE;
$this->checks['permissions']['STATUS_MSG'] = _("Failed");
$this->checks['permissions']['ERROR_MSG'] =
sprintf(_("The specified user '%s' does not have full access to your ldap database."), $config->current['ADMINDN']);
return FALSE;
}
/* Try to remove created entry */
$res = $ldap->rmDir($dn);
$ldap->cat($dn);
if ($ldap->count()) {
new log("view", "setup/".get_class($this), $dn, array(), $ldap->get_error());
$this->checks['permissions']['STATUS'] = FALSE;
$this->checks['permissions']['STATUS_MSG'] = _("Failed");
$this->checks['permissions']['ERROR_MSG'] =
sprintf(_("The specified user '%s' does not have full access to your ldap database."), $config->current['ADMINDN']);
return FALSE;
}
/* Create & remove of dummy object was successful */
$this->checks['permissions']['STATUS'] = TRUE;
$this->checks['permissions']['STATUS_MSG'] = _("Ok");
$this->checks['permissions']['ERROR_MSG'] = "";
return TRUE;
}
/* Check if there are users which will
* be invisible for FusionDirectory
*/
function check_gosaAccounts()
{
global $config;
$ldap = $config->get_ldap_link();
/* Remember old list of invisible users, to be able to set
* the 'html checked' status for the checkboxes again
*/
$old = $this->users_to_migrate;
$this->users_to_migrate = array();
/* Get all invisible users */
$ldap->cd($config->current['BASE']);
$res = $ldap->search("(&(|(objectClass=posixAccount)(&(objectClass=inetOrgPerson)(objectClass=organizationalPerson))(objectClass=OpenLDAPperson))(!(objectClass=gosaAccount))(!(&(objectClass=Account)(objectClass=sambaSamAccount)))(uid=*))", array("sn","givenName","cn","uid"));
while ($attrs = $ldap->fetch()) {
if (!preg_match("/,dc=addressbook,/", $attrs['dn'])) {
$attrs['checked'] = FALSE;
$attrs['before'] = "";
$attrs['after'] = "";
/* Set objects to selected, that were selected before reload */
if (isset($old[base64_encode($attrs['dn'])])) {
$attrs['checked'] = $old[base64_encode($attrs['dn'])]['checked'];
}
$this->users_to_migrate[base64_encode($attrs['dn'])] = $attrs;
}
}
/* No invisible */
if (!$res) {
$this->checks['users_visible']['STATUS'] = FALSE;
$this->checks['users_visible']['STATUS_MSG'] = _("LDAP query failed");
561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
$this->checks['users_visible']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
} elseif (count($this->users_to_migrate) == 0) {
$this->checks['users_visible']['STATUS'] = TRUE;
$this->checks['users_visible']['STATUS_MSG'] = _("Ok");
$this->checks['users_visible']['ERROR_MSG'] = "";
} else {
$this->checks['users_visible']['STATUS'] = FALSE;
$this->checks['users_visible']['STATUS_MSG'] = "<div style='color:#F0A500'>"._("Warning")."</div>";
$this->checks['users_visible']['ERROR_MSG'] = sprintf(_("Found %s user(s) that will not be visible in FusionDirectory or which are incomplete."),
count($this->users_to_migrate));
$this->checks['users_visible']['ERROR_MSG'] .= "<input type='submit' name='users_visible_migrate' value='"._("Migrate")."...'>";
}
}
/* Start user account migration */
function migrate_gosaAccounts($only_ldif = FALSE)
{
global $config;
$ldap = $config->get_ldap_link();
$this->show_details = $only_ldif;
/* Add gosaAccount objectClass to the selected users */
foreach ($this->users_to_migrate as $key => $dep) {
if ($dep['checked']) {
/* Get old objectClasses */
$ldap->cat($dep['dn'], array("objectClass"));
$attrs = $ldap->fetch();
/* Create new objectClass array */
$new_attrs = array();
$new_attrs['objectClass'] = array("gosaAccount","inetOrgPerson","organizationalPerson","person");
for ($i = 0; $i < $attrs['objectClass']['count']; $i++) {
if (!in_array_ics($attrs['objectClass'][$i], $new_attrs['objectClass'])) {
$new_attrs['objectClass'][] = $attrs['objectClass'][$i];
}
}
/* Set info attributes for current object,
* or write changes to the ldap database
*/
if ($only_ldif) {
$this->users_to_migrate[$key]['before'] = $this->array_to_ldif($attrs);
$this->users_to_migrate[$key]['after'] = $this->array_to_ldif($new_attrs);
} else {
$ldap->cd($attrs['dn']);
if (!$ldap->modify($new_attrs)) {
msg_dialog::display(_("Migration error"), sprintf(_("Cannot migrate department '%s':")."<br><br><i>%s</i>", LDAP::fix($attrs['dn']), $ldap->get_error()), ERROR_DIALOG);
return FALSE;
}
}
}
}
return TRUE;
}
/* Check if there are invisible organizational Units */
function check_organizationalUnits()
{
global $config;
$ldap = $config->get_ldap_link();
$old = $this->deps_to_migrate;
$this->deps_to_migrate = array();
/* Skip FusionDirectory internal departments */
$skip_dns = array("/".get_ou('userRDN')."/","/".get_ou('groupRDN')."/","/".get_ou('aclRoleRDN')."/",
631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
"/^ou=people,/","/^ou=groups,/","/^ou=sudoers,/",
"/(,|)ou=configs,/","/(,|)ou=systems,/","/(,|)ou=tokens,/",
"/(,|)ou=apps,/","/(,|)ou=mime,/","/(,|)ou=devices/",
"/ou=snapshots,/","/(,|)dc=addressbook,/","/^(,|)ou=machineaccounts,/","/^ou=opsi,/","/^ou=structures,/",
"/(,|)ou=winstations,/","/^ou=hosts,/","/^ou=computers,/","/^ou=idmap,/","/^ou=Idmap,/","/(,|)ou=roles,/");
/* Get all invisible departments */
$ldap->cd($config->current['BASE']);
$res = $ldap->search("(&(objectClass=organizationalUnit)(!(objectClass=gosaDepartment)))", array("ou","description","dn"));
while ($attrs = $ldap->fetch()) {
$attrs['checked'] = FALSE;
$attrs['before'] = "";
$attrs['after'] = "";
/* Set objects to selected, that were selected before reload */
if (isset($old[base64_encode($attrs['dn'])])) {
$attrs['checked'] = $old[base64_encode($attrs['dn'])]['checked'];
}
$this->deps_to_migrate[base64_encode($attrs['dn'])] = $attrs;
}
/* Filter returned list of departments and ensure that
* FusionDirectory internal departments will not be listed
*/
foreach ($this->deps_to_migrate as $key => $attrs) {
$dn = $attrs['dn'];
$skip = FALSE;
/* Check if this object is an application release object
e.g. groups-> application menus.
*/
if (preg_match("/^.*,[ ]*cn=/", $dn)) {
$cn_dn = preg_replace("/^.*,[ ]*cn=/", "cn=", $dn);
if (in_array($cn_dn, $this->group_list)) {
$skip = TRUE;
}
}
foreach ($skip_dns as $skip_dn) {
if (preg_match($skip_dn, $dn)) {
$skip = TRUE;
}
}
if ($skip) {
unset($this->deps_to_migrate[$key]);
}
}
/* If we have no invisible departments found
* tell the user that everything is ok
*/
if (!$res) {
$this->checks['deps_visible']['STATUS'] = FALSE;
$this->checks['deps_visible']['STATUS_MSG'] = _("LDAP query failed");
$this->checks['deps_visible']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
} elseif (count($this->deps_to_migrate) == 0 ) {
$this->checks['deps_visible']['STATUS'] = TRUE;
$this->checks['deps_visible']['STATUS_MSG'] = _("Ok");
$this->checks['deps_visible']['ERROR_MSG'] = "";
} else {
$this->checks['deps_visible']['STATUS'] = TRUE;
$this->checks['deps_visible']['STATUS_MSG'] = '<font style="color:#FFA500">'._("Warning").'</font>';
$this->checks['deps_visible']['ERROR_MSG'] = sprintf(_("Found %s department(s) that will not be visible in FusionDirectory."), count($this->deps_to_migrate));
$this->checks['deps_visible']['ERROR_MSG'] .= " <input type='submit' name='deps_visible_migrate' value='"._("Migrate")."...'>";
}
}
/* Start deparmtment migration */
701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
function migrate_organizationalUnits($only_ldif = FALSE)
{
global $config;
$ldap = $config->get_ldap_link();
$this->show_details = $only_ldif;
/* Add gosaDepartment objectClass to each selected entry */
foreach ($this->deps_to_migrate as $key => $dep) {
if ($dep['checked']) {
/* Get current objectClasses */
$ldap->cat($dep['dn'], array("objectClass","description"));
$attrs = $ldap->fetch();
/* Create new objectClass attribute including gosaDepartment*/
$new_attrs = array();
for ($i = 0; $i < $attrs['objectClass']['count']; $i++) {
$new_attrs['objectClass'][] = $attrs['objectClass'][$i];
}
$new_attrs['objectClass'][] = "gosaDepartment";
/* Append description it is missing */
if (!isset($attrs['description'])) {
$new_attrs['description'][] = "GOsa department";
}
/* Depending on the parameter >only_diff< we save the changes as ldif
* or we write our changes directly to the ldap database
*/
if ($only_ldif) {
$this->deps_to_migrate[$key]['before'] = $this->array_to_ldif($attrs);
$this->deps_to_migrate[$key]['after'] = $this->array_to_ldif($new_attrs);
} else {
$ldap->cd($attrs['dn']);
if (!$ldap->modify($new_attrs)) {
msg_dialog::display(_("Migration error"), sprintf(_("Cannot migrate department '%s':")."<br><br><i>%s</i>", LDAP::fix($attrs['dn']), $ldap->get_error()), ERROR_DIALOG);
return FALSE;
}
}
}
}
return TRUE;
}
/* Check Acls if there is at least one object with acls defined */
function check_administrativeAccount()
{
global $config;
/* Reset settings */
$FD_1_0_8_found = FALSE;
$this->migrate_users = array();
$this->acl_migrate_dialog = FALSE;
$this->migrate_acl_base_entry = "";
$valid_admin = FALSE;
/* Establish ldap connection */
$ldap = $config->get_ldap_link();
$ldap->cd($config->current['BASE']);
$res = $ldap->cat($config->current['BASE']);
if (!$res) {
$this->checks['acls']['STATUS'] = FALSE;
$this->checks['acls']['STATUS_MSG'] = _("LDAP query failed");
$this->checks['acls']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
} else {
$FD_1_0_8_found = FALSE; // GOsa 2.6 Account found
$FD_1_0_7_found = FALSE; // GOsa 2.5 Account found, allow migration
771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
$attrs = $ldap->fetch();
/* Collect a list of available FusionDirectory users and groups */
$users = array();
$ldap->search("(&(objectClass=gosaAccount)(objectClass=person)".
"(objectClass=inetOrgPerson)(objectClass=organizationalPerson))", array("uid","dn"));
while ($user_attrs = $ldap->fetch()) {
$users[$user_attrs['dn']] = $user_attrs['uid'][0];
$rusers[$user_attrs['uid'][0]] = $user_attrs['dn'];
}
$groups = array();
$ldap->search("objectClass=posixGroup", array("cn","dn"));
while ($group_attrs = $ldap->fetch()) {
$groups[$group_attrs['dn']] = $group_attrs['cn'][0];
}
/* Check if a valid FusionDirectory 1.0.8 admin exists
-> gosaAclEntry for an existing and accessible user.
*/
$valid_users = "";
$valid_groups = "";
if (isset($attrs['gosaAclEntry'])) {
$acls = $attrs['gosaAclEntry'];
for ($i = 0; $i < $acls['count']; $i++) {
$acl = $acls[$i];
$tmp = explode(":", $acl);
if ($tmp[1] == "subtree") {
/* Check if acl owner is a valid FusionDirectory user account */
$ldap->cat(base64_decode($tmp[2]), array("gosaAclTemplate"), '(gosaAclTemplate=*:all;cmdrw)');
if ($ldap->count()) {
$members = explode(",", $tmp[3]);
foreach ($members as $member) {
$member = base64_decode($member);
if (isset($users[$member])) {
if (!$valid_admin) {
$valid_admin = $member;
}
$valid_users .= $users[$member].", ";
$FD_1_0_8_found = TRUE;
}
if (isset($groups[$member])) {
$ldap->cat($member);
$group_attrs = $ldap->fetch();
$val_users = "";
if (isset($group_attrs['memberUid'])) {
for ($e = 0; $e < $group_attrs['memberUid']['count']; $e ++) {
if (isset($rusers[$group_attrs['memberUid'][$e]])) {
if (!$valid_admin) {
$valid_admin = $rusers[$group_attrs['memberUid'][$e]];
}
$val_users .= $group_attrs['memberUid'][$e].", ";
}
}
}
if (!empty($val_users)) {
$valid_groups .= $groups[$member]."(<i>".trim($val_users, ", ")."</i>), ";
$FD_1_0_8_found = TRUE;
}
}
}
}
}
}
}
/* Try to find an old FD 1.0.7 administrator account that may be migrated */
if (!$FD_1_0_8_found) {
841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910
$valid_users = "";
$valid_groups = "";
if (isset($attrs['gosaAclEntry'])) {
$acls = $attrs['gosaAclEntry'];
for ($i = 0; $i < $acls['count']; $i++) {
$acl = $acls[$i];
$tmp = explode(":", $acl);
if ($tmp[1] == "psub") {
$members = explode(",", $tmp[2]);
foreach ($members as $member) {
$member = base64_decode($member);
if (isset($users[$member])) {
if (preg_match("/all;cmdrw/i", $tmp[3])) {
if (!$valid_admin) {
$valid_admin = $member;
}
$valid_users .= $users[$member].", ";
$FD_1_0_7_found = TRUE;
}
}
if (isset($groups[$member])) {
if (preg_match("/all;cmdrw/i", $tmp[3])) {
$ldap->cat($member);
$group_attrs = $ldap->fetch();
$val_users = "";
if (isset($group_attrs['memberUid'])) {
for ($e = 0; $e < $group_attrs['memberUid']['count']; $e++) {
if (isset($rusers[$group_attrs['memberUid'][$e]])) {
if (!$valid_admin) {
$valid_admin = $rusers[$group_attrs['memberUid'][$e]];
}
$val_users .= $group_attrs['memberUid'][$e].", ";
}
}
}
if (!empty($val_users)) {
$valid_groups .= $groups[$member]."(<i>".trim($val_users, ", ")."</i>), ";
$FD_1_0_7_found = TRUE;
}
}
}
}
} elseif ($tmp[1] == "role") {
/* Check if acl owner is a valid FusionDirectory user account */
$ldap->cat(base64_decode($tmp[2]), array("gosaAclTemplate"));
$ret = $ldap->fetch();
if (isset($ret['gosaAclTemplate'])) {
$cnt = $ret['gosaAclTemplate']['count'];
for ($e = 0; $e < $cnt; $e++) {
$a_str = $ret['gosaAclTemplate'][$e];
if (preg_match("/^[0-9]*:psub:/", $a_str) && preg_match("/:all;cmdrw$/", $a_str)) {
$members = explode(",", $tmp[3]);
foreach ($members as $member) {
$member = base64_decode($member);
if (isset($users[$member])) {
if (!$valid_admin) {
$valid_admin = $member;
}
$valid_users .= $users[$member].", ";
$FD_1_0_7_found = TRUE;
}
if (isset($groups[$member])) {
$ldap->cat($member);
$group_attrs = $ldap->fetch();
$val_users = "";
911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980
if (isset($group_attrs['memberUid'])) {
for ($e = 0; $e < $group_attrs['memberUid']['count']; $e ++) {
if (isset($rusers[$group_attrs['memberUid'][$e]])) {
if (!$valid_admin) {
$valid_admin = $rusers[$group_attrs['memberUid'][$e]];
}
$val_users .= $group_attrs['memberUid'][$e].", ";
}
}
}
if (!empty($val_users)) {
$valid_groups .= $groups[$member]."(<i>".trim($val_users, ", ")."</i>), ";
$FD_1_0_7_found = TRUE;
}
}
}
}
}
}
}
}
}
}
/* Print out results */
if ($FD_1_0_7_found) {
$str = "";
if (!empty($valid_groups)) {
$str .= "<i>".sprintf(_("FD 1.0.7 administrator accounts found: %s"), trim($valid_groups, ", "))."</i><br>";
}
$this->checks['acls']['STATUS'] = FALSE;
$this->checks['acls']['STATUS_MSG'] = _("Failed");
$this->checks['acls']['ERROR_MSG'] = $str;
$this->checks['acls']['ERROR_MSG'] .= _("There is no valid FusionDirectory 1.0.8 administrator account inside your LDAP.")." ";
$this->checks['acls']['ERROR_MSG'] .= "<input type='submit' name='migrate_acls' value='"._("Migrate")."'>";
$this->checks['acls']['ERROR_MSG'] .= "<input type='submit' name='create_acls' value='"._("Create")."'>";
} elseif ($FD_1_0_8_found) {
$str = "";
if (!empty($valid_users)) {
$str .= "<b>"._("Users")."</b>: ".trim($valid_users, ", ")."<br>";
}
if (!empty($valid_groups)) {
$str .= "<b>"._("Groups")."</b>: ".trim($valid_groups, ", ")."<br>";
}
$this->checks['acls']['STATUS'] = TRUE;
$this->checks['acls']['STATUS_MSG'] = _("Ok");
$this->checks['acls']['ERROR_MSG'] = $str;
$this->valid_admin = $valid_admin;
} else {
$this->checks['acls']['STATUS'] = FALSE;
$this->checks['acls']['STATUS_MSG'] = _("Failed");
$this->checks['acls']['ERROR_MSG'] = _("There is no FusionDirectory administrator account inside your LDAP.")." ";
$this->checks['acls']['ERROR_MSG'] .= "<input type='submit' name='create_acls' value='"._("Create")."'>";
}
}
// Reload base OC
$this->checkBaseOC();
return $FD_1_0_8_found;
}
/* Check if default roles and groupes have been inserted */
function check_defaultACLs()
{
global $config;
$ldap = $config->get_ldap_link();
$ldap->cd($config->current['BASE']);
$res = $ldap->cat($config->current['BASE']);
if (!$res) {
981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050
$this->checks['default_acls']['STATUS'] = FALSE;
$this->checks['default_acls']['STATUS_MSG'] = _("LDAP query failed");
$this->checks['default_acls']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
return FALSE;
}
$existings = 0;
foreach ($this->defaultRoles as $role) {
$dn = 'cn='.$role['cn'].','.get_ou('aclRoleRDN').$config->current['BASE'];
$ldap->cat($dn, array('dn'));
if ($ldap->count() > 0) {
$existings++;
}
}
$this->checks['default_acls']['STATUS'] = ($existings == count($this->defaultRoles));
if ($existings == 0) {
$this->checks['default_acls']['STATUS_MSG'] = _('Default ACL roles have not been inserted');
} elseif ($existings < count($this->defaultRoles)) {
$this->checks['default_acls']['STATUS_MSG'] = _('Some default ACL roles are missing');
} else {
$this->checks['default_acls']['STATUS_MSG'] = _('Default ACL roles have been inserted');
}
if ($this->checks['default_acls']['STATUS'] === FALSE) {
$this->checks['default_acls']['ERROR_MSG'] = ' <input type="submit"
name="root_add_defaultroles" value="'._('Migrate').'"/>';
} else {
$this->checks['default_acls']['ERROR_MSG'] = '';
}
}
function insert_defaultRoles()
{
global $config;
$ldap = $config->get_ldap_link();
$ldap->cd($config->current['BASE']);
foreach ($this->defaultRoles as $role) {
$dn = 'cn='.$role['cn'].','.get_ou('aclRoleRDN').$config->current['BASE'];
$ldap->cat($dn);
if ($ldap->count() == 0) {
$ldap->cd($dn);
$ldap->add($role);
if (!$ldap->success()) {
msg_dialog::display(
_("Migration error"),
sprintf(
_("Cannot add ACL role '%s':")."<br/><br/><i>%s</i>",
LDAP::fix($dn), $ldap->get_error()
),
ERROR_DIALOG
);
return FALSE;
}
}
}
return TRUE;
}
function create_admin($only_ldif = FALSE)
{
global $config;
/* Reset '' */
$this->acl_create_changes = "";
/* Object that should receive admin acls */
$dn = $this->acl_create_selected;
/* Get collected configuration settings */
$ldap = $config->get_ldap_link();
1051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120
$ldap->search("(&(objectClass=gosaRole)(gosaAclTemplate=*:all;cmdrw))", array('dn'));
if ($attrs = $ldap->fetch()) {
$roledn = $attrs['dn'];
} else {
$roledn = 'cn=admin,'.get_ou('aclRoleRDN').$config->current['BASE'];
if (!$only_ldif) {
$ldap->create_missing_trees(get_ou('aclRoleRDN').$config->current['BASE']);
$ldap->cd($roledn);
$attrs_role = array(
'cn' => 'admin',
'description' => _('Give all rights on all objects'),
'objectclass' => array( 'top', 'gosaRole' ),
'gosaAclTemplate' => '0:all;cmdrw'
);
$ldap->add($attrs_role);
if (!$ldap->success()) {
msg_dialog::display(_("Migration error"), sprintf(_("Cannot add ACL role '%s':")."<br><br><i>%s</i>", LDAP::fix($roledn), $ldap->get_error()), ERROR_DIALOG);
return FALSE;
}
}
}
/* Get current base attributes */
$ldap->cd($config->current['BASE']);
$ldap->cat($config->current['BASE'], array("dn","objectClass","gosaAclEntry"));
$attrs = $ldap->fetch();
/* Add acls for the selcted user to the base */
$attrs_new = array();
$attrs_new['objectClass'] = $attrs['objectClass'];
unset($attrs_new['objectClass']['count']);
if (!in_array_ics('gosaAcl', $attrs_new['objectClass'])) {
$attrs_new['objectClass'][] = 'gosaAcl';
}
$acl = "0:subtree:".base64_encode($roledn).':'.base64_encode($dn); //FIXME
$attrs_new['gosaAclEntry'][] = $acl;
if (isset($attrs['gosaAclEntry'])) {
for ($i = 0; $i < $attrs['gosaAclEntry']['count']; $i ++) {
$prio = preg_replace("/[:].*$/", "", $attrs['gosaAclEntry'][$i]);
$rest = preg_replace("/^[^:]+/", "", $attrs['gosaAclEntry'][$i]);
$data = ($prio + 1).$rest;
$attrs_new['gosaAclEntry'][] = $data;
}
}
if ($only_ldif) {
$this->acl_create_changes = "\n".($ldap->fix($config->current['BASE']))."\n";
$this->acl_create_changes .= $this->array_to_ldif($attrs)."\n";
$this->acl_create_changes .= "\n".($ldap->fix($config->current['BASE']))."\n";
$this->acl_create_changes .= $this->array_to_ldif($attrs_new);
} else {
$ldap->cd($config->current['BASE']);
$ldap->modify($attrs_new);
if (!$ldap->success()) {
msg_dialog::display(_("Migration error"), sprintf(_("Cannot add ACL for user '%s':")."<br><br><i>%s</i>", LDAP::fix($dn), $ldap->get_error()), ERROR_DIALOG);
return FALSE;
} else {
return TRUE;
}
}
}
function create_admin_user()
{
global $config;
1121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190
$pw1 = $pw2 = "";
$uid = "";
$ldap = $config->get_ldap_link();
if (isset($_POST['new_user_uid'])) {
$uid = $_POST['new_user_uid'];
}
if (isset($_POST['new_user_password'])) {
$pw1 = $_POST['new_user_password'];
}
if (isset($_POST['new_user_password2'])) {
$pw2 = $_POST['new_user_password2'];
}
$ldap->cd($config->current['BASE']);
$ldap->search("(uid=".$uid.")");
if ($ldap->count()) {
msg_dialog::display(_("Input error"), msgPool::duplicated(_("Uid")), ERROR_DIALOG);
return FALSE;
}
if (empty($pw1) || empty($pw2) | ($pw1 != $pw2)) {
msg_dialog::display(_("Password error"), _("Provided passwords do not match!"), ERROR_DIALOG);
return FALSE;
}
if (!tests::is_uid($uid) || empty($uid)) {
msg_dialog::display(_("Input error"), _("Specify a valid user ID!"), ERROR_DIALOG);
return FALSE;
}
/* Get current base attributes */
$ldap->cd($config->current['BASE']);
$people_ou = trim(get_ou('userRDN'));
if (!empty($people_ou)) {
$people_ou .= ",";
}
if ($config->get_cfg_value('accountPrimaryAttribute') == 'cn') {
$dn = "cn=System Administrator-".$uid.",".$people_ou.$config->current['BASE'];
} else {
$dn = "uid=".$uid.",".$people_ou.$config->current['BASE'];
}
$hash = passwordMethod::make_hash($pw2, $config->get_cfg_value('passwordDefaultHash', 'ssha'));
$new_user = array();
$new_user['objectClass'] = array("top","person","gosaAccount","organizationalPerson","inetOrgPerson");
$new_user['givenName'] = "System";
$new_user['sn'] = "Administrator";
$new_user['cn'] = "System Administrator-".$uid;
$new_user['uid'] = $uid;
$new_user['userPassword'] = $hash;
$ldap->cd($config->current['BASE']);
$ldap->cat($dn, array("dn"));
if ($ldap->count()) {
msg_dialog::display(_("Error"), sprintf(_("Adding an administrator user failed: object '%s' already exists!"), LDAP::fix($dn)), ERROR_DIALOG);
return FALSE;
}
$ldap->create_missing_trees(preg_replace("/^[^,]+,/", "", $dn));
$ldap->cd($dn);
$res = $ldap->add($new_user);
$this->acl_create_selected = $dn;
$this->create_admin();
1191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260
if (!$res) {
msg_dialog::display(_("LDAP error"), $ldap->get_error(), ERROR_DIALOG);
return FALSE;
}
$this->acl_create_dialog = FALSE;
$this->check_administrativeAccount();
return TRUE;
}
function migrate_outside_groups($perform = FALSE)
{
global $config;
$ldap = $config->get_ldap_link();
$ldap->cd($config->current['BASE']);
/* Check if there was a destination department posted */
if (isset($_POST['move_group_to'])) {
$destination_dep = $_POST['move_group_to'];
} else {
msg_dialog::display(_("LDAP error"), _("Cannot move users to the requested department!"), ERROR_DIALOG);
return FALSE;
}
foreach ($this->outside_groups as $b_dn => $data) {
$this->outside_groups[$b_dn]['ldif'] = "";
if ($data['selected']) {
$dn = base64_decode($b_dn);
$d_dn = preg_replace("/,.*$/", ",".base64_decode($destination_dep), $dn);
if (!$perform) {
$this->outside_groups[$b_dn]['ldif'] = _("Group will be moved from").":<br>\t".($ldap->fix($dn))."<br>"._("to").":<br>\t".($ldap->fix($d_dn));
/* Check if there are references to this object */
$ldap->search("(&(member=".LDAP::prepare4filter($dn).")(|(objectClass=gosaGroupOfNames)(objectClass=groupOfNames)))", array('dn'));
$refs = "";
while ($attrs = $ldap->fetch()) {
$ref_dn = $attrs['dn'];
$refs .= "<br />\t".$ref_dn;
}
if (!empty($refs)) {
$this->outside_groups[$b_dn]['ldif'] .= "<br /><br /><i>"._("Updating following references too").":</i>".$refs;
}
} else {
$this->move($dn, $d_dn);
}
}
}
}
function migrate_outside_users($perform = FALSE)
{
global $config;
$ldap = $config->get_ldap_link();
$ldap->cd($config->current['BASE']);
/* Check if there was a destination department posted */
if (isset($_POST['move_user_to'])) {
$destination_dep = $_POST['move_user_to'];
} else {
msg_dialog::display(_("LDAP error"), _("Cannot move users to the requested department!"), ERROR_DIALOG);
return FALSE;
}
foreach ($this->outside_users as $b_dn => $data) {
$this->outside_users[$b_dn]['ldif'] = "";
if ($data['selected']) {