config = $config;
$this->ui = $ui;
$this->storagePoints = array(get_ou("userRDN"));
// Build filter
if (session::global_is_set(get_class($this)."_filter")){
$filter= session::global_get(get_class($this)."_filter");
} else {
$filter = new filter(get_template_path("user-filter.xml", true));
$filter->setObjectStorage($this->storagePoints);
}
$this->setFilter($filter);
// Build headpage
$headpage = new listing(get_template_path("user-list.xml", true));
$headpage->registerElementFilter("lockLabel", "userManagement::filterLockLabel");
$headpage->registerElementFilter("lockImage", "userManagement::filterLockImage");
$headpage->registerElementFilter("filterProperties", "userManagement::filterProperties");
$headpage->setFilter($filter);
// Add copy&paste and snapshot handler.
if ($this->config->boolValueIsTrue("main", "copyPaste")){
$this->cpHandler = new CopyPasteHandler($this->config);
}
if($this->config->get_cfg_value("enableSnapshots") == "true"){
$this->snapHandler = new SnapshotHandler($this->config);
}
parent::__construct($config, $ui, "users", $headpage);
// Register special user actions
$this->registerAction("lock", "lockEntry");
$this->registerAction("lockUsers", "lockUsers");
$this->registerAction("unlockUsers", "lockUsers");
$this->registerAction("new_template", "newTemplate");
$this->registerAction("newfromtpl", "newUserFromTemplate");
$this->registerAction("templateContinue", "templateContinue");
$this->registerAction("templatize", "templatizeUsers");
$this->registerAction("templatizeContinue", "templatizeContinue");
$this->registerAction("password", "changePassword");
$this->registerAction("passwordQueue", "handlePasswordQueue");
$this->registerAction("passwordCancel", "closeDialogs");
$this->registerAction("sendMessage", "sendMessage");
$this->registerAction("saveEventDialog", "saveEventDialog");
$this->registerAction("abortEventDialog", "closeDialogs");
// Register shortcut icon actions
$this->registerAction("edit_user","editEntry");
$this->registerAction("edit_posixAccount","editEntry");
$this->registerAction("edit_mailAccount","editEntry");
$this->registerAction("edit_sambaAccount","editEntry");
$this->registerAction("edit_netatalk","editEntry");
$this->registerAction("edit_environment","editEntry");
$this->registerAction("edit_gofaxAccount","editEntry");
$this->registerAction("edit_phoneAccount","editEntry");
}
// Inject user actions
function detectPostActions()
{
$action = management::detectPostActions();
if(isset($_POST['template_continue'])) $action['action'] = "templateContinue";
if(isset($_POST['templatize_continue'])) $action['action'] = "templatizeContinue";
if(isset($_POST['save_event_dialog'])) $action['action'] = "saveEventDialog";
if(isset($_POST['abort_event_dialog'])) $action['action'] = "abortEventDialog";
if(isset($_POST['password_cancel'])){
$action['action'] = "passwordCancel";
}elseif((count($this->pwd_change_queue) || isset($_POST['password_finish']))){
$action['action'] = "passwordQueue";
}
return($action);
}
function editEntry($action="",$target=array(),$all=array(), $altTabClass ="", $altTabType = "", $altAclCategory="")
{
management::editEntry($action,$target);
if(preg_match("/^edit_/",$action)){
$tab = preg_replace("/^edit_/","",$action);
if(isset($this->tabObject->by_object[$tab])){
$this->tabObject->current = $tab;
}else{
trigger_error("Unknown tab: ".$tab);
}
}
}
function closeDialogs()
{
management::closeDialogs();
$this->pwd_change_queue = array();
}
/*! \brief Sends a message to a set of users using gosa-si events.
*/
function sendMessage($action="",$target=array(),$all=array())
{
if(class_available("DaemonEvent")){
$uids = array();
$ldap = $this->config->get_ldap_link();
$ldap->cd($this->config->current['BASE']);
foreach($target as $dn){
$ldap->cat($dn,array('uid'));
$attrs = $ldap->fetch();
if(isset($attrs['uid'][0])){
$uids[] = $attrs['uid'][0];
}
}
if(count($uids)){
$events = DaemonEvent::get_event_types(USER_EVENT);
$event = "DaemonEvent_notify";
if(isset($events['BY_CLASS'][$event])){
$type = $events['BY_CLASS'][$event];
$this->dialogObject = new $type['CLASS_NAME']($this->config);
$this->dialogObject->add_users($uids);
$this->dialogObject->set_type(SCHEDULED_EVENT);
}
}
}
}
/*! \brief Sends a message to a set of users using gosa-si events.
*/
function saveEventDialog()
{
$this->dialogObject->save_object();
$msgs = $this->dialogObject->check();
if(count($msgs)){
msg_dialog::displayChecks($msgs);
}else{
$o_queue = new gosaSupportDaemon();
$o_queue->append($this->dialogObject);
if($o_queue->is_error()){
msg_dialog::display(_("Infrastructure error"), msgPool::siError($o_queue->get_error()),ERROR_DIALOG);
}
$this->closeDialogs();
}
}
/*! \brief Intiates template creation.
*/
function newTemplate($action,$entry)
{
$this->newEntry();
$this->tabObject->set_template_mode ();
}
/*! \brief Queues a set of users for password changes
*/
function changePassword($action="",$target=array(),$all=array())
{
$this->dn ="";
$this->pwd_change_queue = $target;
// Check permisions
$disallowed = array();
foreach($this->pwd_change_queue as $key => $dn){
if(!preg_match("/w/",$this->ui->get_permissions($dn,$this->aclCategory."/password"))){
unset($this->pwd_change_queue[$key]);
$disallowed[] = $dn;
}
}
if(count($disallowed)){
msg_dialog::display(_("Permission"),msgPool::permModify($disallowed),INFO_DIALOG);
}
// Now display change dialog.
return($this->handlePasswordQueue());
}
function handlePasswordQueue()
{
// Get next entry from queue.
if(empty($this->dn) && count($this->pwd_change_queue)){
$this->dn = array_pop($this->pwd_change_queue);
set_object_info($this->dn);
$smarty = get_smarty();
return ($smarty->fetch(get_template_path('password.tpl', TRUE)));
}
// Check permissions
$dn = $this->dn;
$acl = $this->ui->get_permissions($dn, "users/password");
$cacl= $this->ui->get_permissions($dn, "users/user");
if (preg_match('/w/', $acl) || preg_match('/c/', $cacl)){
$message= array();
if ($_POST['new_password'] != $_POST['repeated_password']){
$message[]= _("The passwords you've entered as 'New password' and 'Repeated new password' do not match.");
} else {
if ($_POST['new_password'] == ""){
$message[] = msgPool::required(_("New password"));
}
}
// Display errors
if (count($message) != 0){
msg_dialog::displayChecks($message);
$smarty = get_smarty();
return($smarty->fetch(get_template_path('password.tpl', TRUE)));
}
// Change cassword
if(!change_password ($this->dn, $_POST['new_password'])){
return($smarty->fetch(get_template_path('password.tpl', TRUE)));
}
if ($this->config->get_cfg_value("passwordHook") != ""){
exec($this->config->get_cfg_value("passwordHook")." ".$username." ".$_POST['new_password'], $resarr);
}
new log("modify","users/".get_class($this),$this->dn,array(),"Password has been changed");
$this->dn ="";
} else {
msg_dialog::display(_("Password change"),
_("You have no permission to change this users password!"),
WARNING_DIALOG);
}
// Cleanup
if(!count($this->pwd_change_queue)){
$this->remove_lock();
$this->closeDialogs();
}else{
return($this->handlePasswordQueue());
}
}
/*! \brief Save user modifications.
* Whenever we save a 'new' user, request a password change for him.
*/
function saveChanges()
{
management::saveChanges();
if($this->last_dn == "new"){
$this->pwd_change_queue[] = $this->last_tabObject->dn;
return($this->handlePasswordQueue());
}
}
/*! \brief Intiates user creation.
* If we've user templates, then the user will be asked to use to use one.
* -> See 'templateContinue' for further handling.
*/
function newUserFromTemplate($action="",$target=array(),$all=array())
{
// Call parent method, it knows whats to do, locking and so on ...
management::newEntry($action,$target,$all);
// Reset uid selection.
$this->got_uid= "";
// Use template if there are any of them
$templates = array();
$templates['none']= _("none");
$templates = array_merge($templates,$this->get_templates());
// We've templates, so preset the current template and display the input dialog.
if (count($templates)){
$smarty = get_smarty();
foreach(array("sn", "givenName", "uid", "got_uid") as $attr){
$smarty->assign("$attr", "");
}
$smarty->assign("template", array_pop($target));
$smarty->assign("templates", $templates);
$smarty->assign("edit_uid", "");
return($smarty->fetch(get_template_path('template.tpl', TRUE)));
// -> See 'templateContinue' for further handling!
}
}
/*! \brief Intiates user creation.
* If we've user templates, then the user will be asked
* if he wants to use one.
* -> See 'templateContinue' for further handling.
*/
function newEntry($action="",$target=array(),$all=array(), $altTabClass ="", $altTabType = "", $altAclCategory="")
{
// Call parent method, it manages everything, locking, object creation...
management::newEntry($action,$target,$all);
// If we've at least one template, then ask the user if he wants to use one?
$templates = array();
$templates['none']= _("none");
$templates = array_merge($templates,$this->get_templates());
// Display template selection
if (count($templates)){
$smarty = get_smarty();
// Set default variables, normally empty.
foreach(array("sn", "givenName", "uid", "got_uid") as $attr){
$smarty->assign($attr, "");
}
$smarty->assign("template", "none");
$smarty->assign("templates", $templates);
$smarty->assign("edit_uid", "");
return($smarty->fetch(get_template_path('template.tpl', TRUE)));
// -> See 'templateContinue' for further handling!
}
}
/* !\brief This method is called whenever a template selection was displayed.
* Here we act on the use selection.
* - Does the user want to create a user from template?
* - Create user without template?
* - Input correct, every value given and valid?
*/
function templateContinue()
{
// Get the list of available templates.
$templates = array();
$templates['none']= _("none");
$templates = array_merge($templates,$this->get_templates());
// Input validation, if someone wants to create a user from a template
// then validate the given values.
$message = array();
if(!isset($_POST['template']) || (empty($_POST['template']))){
$message[]= msgPool::invalid(_("Template"));
}
if(!isset($_POST['sn']) || (empty($_POST['sn']))){
$message[]= msgPool::required(_("Name"));
}
if(!isset($_POST['givenName']) || (empty($_POST['givenName']))){
$message[]= msgPool::required(_("Given name"));
}
/********************
* 1 We've had input errors - Display errors and show input dialog again.
********************/
if (count($message) > 0){
msg_dialog::displayChecks($message);
// Preset input fields with user input.
$smarty = get_smarty();
foreach(array("sn", "givenName", "uid", "template") as $attr){
if(isset($_POST[$attr])){
$smarty->assign("$attr", get_post($attr));
}else{
$smarty->assign("$attr", "");
}
}
$smarty->assign("templates",$templates);
$smarty->assign("got_uid", $this->got_uid);
$smarty->assign("edit_uid",false);
return($smarty->fetch(get_template_path('template.tpl', TRUE)));
}
/********************
* 2 There was a template selected, now ask for the uid.
********************/
if ($_POST['template'] != 'none' && !isset($_POST['uid'])){
// Remember user input.
$smarty = get_smarty();
$this->sn = $_POST['sn'];
$this->givenName = $_POST['givenName'];
// Avoid duplicate entries, check if such a user already exists.
$dn= preg_replace("/^[^,]+,/i", "", $_POST['template']);
$ldap= $this->config->get_ldap_link();
$ldap->cd ($dn);
$ldap->search ("(&(sn=".normalizeLdap($this->sn).")(givenName=".normalizeLdap($this->givenName)."))", array("givenName"));
if ($ldap->count () != 0){
msg_dialog::displayChecks(array(msgPool::duplicated(_("Name"))));
}else{
// Preset uid field by using the idGenerator
$attributes= array('sn' => $this->sn, 'givenName' => $this->givenName);
if ($this->config->get_cfg_value("idGenerator") != ""){
$uids= gen_uids ($this->config->get_cfg_value("idGenerator"), $attributes);
if (count($uids)){
$smarty->assign("edit_uid", "false");
$smarty->assign("uids", $uids);
$this->uid= current($uids);
}
} else {
$smarty->assign("edit_uid", "");
$this->uid= "";
}
$this->got_uid= true;
}
// Assign user input
foreach(array("sn", "givenName", "uid", "got_uid") as $attr){
$smarty->assign("$attr", $this->$attr);
}
if (isset($_POST['template'])){
$smarty->assign("template", $_POST['template']);
}
$smarty->assign("templates",$templates);
return($smarty->fetch(get_template_path('template.tpl', TRUE)));
}
/********************
* 3 No template - Ok. Lets fill the data into the user object and skip templating here.
********************/
if ($_POST['template'] == 'none'){
foreach(array("sn", "givenName", "uid") as $attr){
if (isset($_POST[$attr])){
$this->tabObject->by_object['user']->$attr= $_POST[$attr];
}
}
// The user Tab object is already instantiated, so just go back and let the
// management class do the rest.
return("");
}
/********************
* 4 Template selected and uid given - Ok, then lets adapt tempalte values.
********************/
if(isset($_POST['uid'])){
// Move user supplied data to sub plugins
foreach(array("uid","sn","givenName") as $attr){
$this->$attr = $_POST[$attr];
$this->tabObject->$attr = $this->$attr;
$this->tabObject->by_object['user']->$attr = $this->$attr;
}
// Adapt template values.
$template_dn = $_POST['template'];
$this->tabObject->adapt_from_template($template_dn, array("uid","cn","givenName","sn"));
$template_base = preg_replace("/^[^,]+,".preg_quote(get_people_ou(), '/')."/", '', $template_dn);
$this->tabObject->by_object['user']->base= $template_base;
// The user Tab object is already instantiated, so just go back and let the
// management class do the rest.
return("");
}
}
/* !\brief This method applies a template to a set of users.
*/
function templatizeUsers($action="",$target=array(),$all=array())
{
$this->dns = array();
if(count($target)){
// Get the list of available templates.
$templates = $this->get_templates();
// Check entry locking
foreach($target as $dn){
if (($user= get_lock($dn)) != ""){
return(gen_locked_message ($user, $dn));
}
$this->dns[] = $dn;
}
// Display template
$smarty = get_smarty();
$smarty->assign("templates", $templates);
return($smarty->fetch(get_template_path('templatize.tpl', TRUE)));
}
}
/* !\brief This method is called whenever the templatize dialog was used.
*/
function templatizeContinue()
{
// Template readable?
$template= get_post('template');
$acl = $this->ui->get_permissions($template, $this->aclCategory."/".$this->aclPlugin);
if (preg_match('/r/', $acl)){
$tab = $this->tabClass;
foreach ($this->dns as $dn){
// User writeable
$acl = $this->ui->get_permissions($dn, $this->aclCategory."/".$this->aclPlugin);
if (preg_match('/w/', $acl)){
$this->tabObject= new $tab($this->config, $this->config->data['TABS'][$this->tabType], $dn, $this->aclCategory);
$this->tabObject->adapt_from_template($template, array("sn", "givenName", "uid"));
$this->tabObject->save();
} else {
msg_dialog::display(_("Permission error"), msgPool::permModify($dn), ERROR_DIALOG);
}
}
} else {
msg_dialog::display(_("Permission error"), msgPool::permView($template), ERROR_DIALOG);
}
// Cleanup!
$this->remove_lock();
$this->closeDialogs();
}
/* !\brief Lock/unlock multiple users.
*/
function lockUsers($action,$target,$all)
{
if($action == "lockUsers"){
$this->lockEntry($action,$target, $all, "lock");
}else{
$this->lockEntry($action,$target, $all, "unlock");
}
}
/* !\brief Locks/unlocks the given user(s).
*/
function lockEntry($action,$entry, $all, $type = "toggle")
{
// Filter out entries we are not allowed to modify
$disallowed = array();
$dns = array();
foreach($entry as $dn){
if (!preg_match("/w/",$this->ui->get_permissions($dn,"users/password"))){
$disallowed[] = $dn;
}else{
$allowed[] = $dn;
}
}
if(count($disallowed)){
msg_dialog::display(_("Permission"),msgPool::permDelete($disallowed),INFO_DIALOG);
}
// Try to lock/unlock the rest of the entries.
$ldap = $this->config->get_ldap_link();
foreach($allowed as $dn){
$ldap->cat($dn, array('userPassword'));
if($ldap->count() == 1){
// We can't lock empty passwords.
$val = $ldap->fetch();
if(!isset($val['userPassword'])){
continue;
}
// Detect the password method and try to lock/unlock.
$pwd = $val['userPassword'][0];
$method = passwordMethod::get_method($pwd,$val['dn']);
$success= true;
if($method instanceOf passwordMethod){
if($type == "toggle"){
if($method->is_locked($this->config,$val['dn'])){
$success= $method->unlock_account($this->config,$val['dn']);
}else{
$success= $method->lock_account($this->config,$val['dn']);
}
}elseif($type == "lock" && !$method->is_locked($this->config,$val['dn'])){
$success= $method->lock_account($this->config,$val['dn']);
}elseif($type == "unlock" && $method->is_locked($this->config,$val['dn'])){
$success= $method->unlock_account($this->config,$val['dn']);
}
// Check if everything went fine.
if (!$success){
$hn= $method->get_hash_name();
if (is_array($hn)){
$hn= $hn[0];
}
msg_dialog::display(_("Account locking"),
sprintf(_("Password method '%s' does not support locking. Account (%s) has not been locked!"),
$hn,$dn),WARNING_DIALOG);
}
}else{
// Can't lock unknown methods.
}
}
}
}
/* !\brief This method returns a list of all available templates.
*/
function get_templates()
{
$templates= array();
$ldap= $this->config->get_ldap_link();
foreach ($this->config->departments as $key => $value){
$acl = $this->ui->get_permissions($value,$this->aclCategory."/".$this->aclPlugin);
if (preg_match("/c/",$acl)){
// Search all templates from the current dn.
$ldap->cd (get_people_ou().$value);
$ldap->search ("(objectClass=gosaUserTemplate)", array("uid"));
if ($ldap->count() != 0){
while ($attrs= $ldap->fetch()){
$templates[$ldap->getDN()]= $attrs['uid'][0]." - ".LDAP::fix($key);
}
}
}
}
natcasesort ($templates);
reset ($templates);
return($templates);
}
function copyPasteHandler($action="",$target=array(),$all=array(),
$altTabClass ="", $altTabType = "", $altAclCategory="",$altAclPlugin="")
{
$this->cpHandler->lastdn = "";
$str = management::copyPasteHandler($action,$target,$all);
if($this->cpHandler->lastdn != "" && isset($_POST['passwordTodo']) && $_POST['passwordTodo'] == "new"){
$this->pwd_change_queue[] = $this->cpHandler->lastdn;
return($this->handlePasswordQueue());
}
return($str);
}
static function filterLockImage($userPassword)
{
$image= "images/empty.png";
if(isset($userPassword[0]) && preg_match("/^\{[^\}]/",$userPassword[0])){
if(preg_match("/^[^\}]*+\}!/",$userPassword[0])){
$image= "images/lists/locked.png";
}else{
$image= "images/lists/unlocked.png";
}
}
return $image;
}
static function filterLockLabel($userPassword)
{
$label= "";
if(isset($userPassword[0]) && preg_match("/^\{[^\}]/",$userPassword[0])){
if(preg_match("/^[^\}]*+\}!/",$userPassword[0])){
$label= _("Unlock account");
}else{
$label= _("Lock account");
}
}
return $label;
}
static function filterProperties($row, $classes)
{
$result= "";
$map= array( "gosaAccount" => array( "image" => "plugins/users/images/select_user.png",
"plugin" => "user",
"alt" => _("Generic"),
"title" => _("Edit generic properties")),
"posixAccount" => array("image" => "images/penguin.png",
"plugin" => "posixAccount",
"alt" => _("POSIX"),
"title" => _("Edit POSIX properties")),
"gosaMailAccount" => array("image" => "images/mailto.png",
"alt" => _("Mail"),
"plugin" => "mailAccount",
"title" => _("Edit mail properties")),
"sambaSamAccount" => array("image" => "plugins/systems/images/select_winstation.png",
"plugin" => "sambaAccount",
"alt" => _("Samba"),
"title" => _("Edit samba properties")),
"apple-user" => array("image" => "plugins/netatalk/images/select_netatalk.png",
"plugin" => "netatalk",
"alt" => _("Netatalk"),
"title" => _("Edit netatalk properties")),
"gotoEnvironment" => array("image" => "plugins/users/images/small_environment.png",
"plugin" => "environment",
"alt" => _("Environment"),
"title" => _("Edit environment properties")),
"goFaxAccount" => array("image" => "plugins/users/images/fax_small.png",
"plugin" => "gofaxAccount",
"alt" => _("FAX"),
"title" => _("Edit FAX properties")),
"goFonAccount" => array("image" => "plugins/gofon/images/select_phone.png",
"plugin" => "phoneAccount",
"alt" => _("Phone"),
"title" => _("Edit phone properties")));
// Walk thru map
foreach ($map as $oc => $properties) {
if (in_array_ics($oc, $classes)) {
$result.="";
} else {
$result.="
";
}
}
return $result;
}
}
// vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
?>