1 <?php
2 /*
3 * This code is part of GOsa (http://www.gosa-project.org)
4 * Copyright (C) 2003-2008 GONICUS GmbH
5 *
6 * ID: $$Id$$
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
23 class userManagement extends plugin
24 {
25 /* Plugin definitions */
26 var $plHeadline = "Users";
27 var $plDescription = "Manage users";
28 var $plIcon = "plugins/users/images/user.png";
30 /* Dialog attributes */
31 var $usertab = NULL;
32 var $ui = NULL;
33 var $templates = array();
34 var $got_uid = false;
35 var $CopyPasteHandler = NULL;
36 var $CPPasswordChange = ""; // Contains the entry id which should get a new password
37 var $DivListUsers;
39 var $pwd_change_queue = array();
41 var $start_pasting_copied_objects = FALSE;
42 var $msg_dialog= NULL;
43 var $acl_module = array("users");
44 var $dns = array();
46 // Filter/headpage tests
47 var $filter= null;
48 var $headpage= null;
51 function userManagement(&$config, $ui)
52 {
53 /* Save configuration for internal use */
54 $this->config= &$config;
55 $this->ui= &$ui;
57 /* Copy & Paste handler */
58 if ($this->config->boolValueIsTrue("main", "copyPaste")){
59 $this->CopyPasteHandler= new CopyPasteHandler($this->config);
60 }
62 /* Creat dialog object */
63 $this->DivListUsers = new divListUsers($this->config,$this);
65 }
68 function execute()
69 {
70 /* Call parent execute */
71 plugin::execute();
73 /* LOCK MESSAGE Vars */
74 session::set('LOCK_VARS_TO_USE',array("/^act$/","/^id$/","/^user_edit_/","/^user_del_/","/^item_selected/","/^remove_multiple_users/","/^multiple_edit/","/menu_action/"));
76 $smarty = get_smarty(); // Smarty instance
77 $s_action = ""; // Contains the action to be taken
78 $s_entry = ""; // The value for s_action
80 /* Edit entry button pressed? */
81 if( isset($_GET['act']) && $_GET['act'] == "edit_entry" ){
82 $s_action= "edit";
83 $s_entry= validate($_GET['id']);
84 }
86 /* Test relevant POST values */
87 foreach($_POST as $key => $val){
89 /* Get every possible POST combination and set s_action/s_entry accordingly */
90 foreach(array("del" => "user_del",
91 "edit" => "user_edit",
92 "new" => "user_new",
93 "new_tpl" => "user_tplnew",
94 "del_multiple" => "^remove_multiple_users",
95 "create_user_from_tpl" => "userfrom_tpl",
96 "change_pw" => "user_chgpw",
97 "editPaste" => "editPaste",
98 "copy_multiple" => "multiple_copy_users",
99 "multiple_edit" => "multiple_edit",
100 "cut_multiple" => "multiple_cut_users",
101 "multiple_password_change" => "multiple_password_change",
102 "copy" => "^copy",
103 "toggle_lock_status" => "toggle_lock_status",
104 "cut" => "^cut") as $act => $name){
106 if (preg_match("/".$name.".*/", $key)){
107 $s_action= $act;
108 $s_entry= preg_replace("/".$name."_/i", "", $key);
109 break;
110 }
111 }
113 } /* ...Test POST */
115 /* Remove coordinate prefix from POST, required by some browsers */
116 $s_entry= preg_replace("/_.$/", "", $s_entry);
118 /* Seperate possibly encoded tab and entry, default to tab "user" */
119 if(preg_match("/.*-.*/", $s_entry)){
120 $s_tab= preg_replace("/^[^-]*-/i", "" ,$s_entry);
121 $s_entry= preg_replace("/-[^-]*$/i", "", $s_entry);
122 }else{
123 $s_tab= "user";
124 }
126 if(!$this->config->search($s_tab, 'class',array('tabs'))){
127 $s_tab = "user";
128 }
130 if (isset($_POST['menu_action'])){
132 /* handle C&P from layers menu */
133 if(preg_match("/^multiple_copy_systems/",$_POST['menu_action'])){
134 $s_action = "copy_multiple";
135 }
136 if(preg_match("/^multiple_cut_systems/",$_POST['menu_action'])){
137 $s_action = "cut_multiple";
138 }
139 if(preg_match("/^editPaste/",$_POST['menu_action'])){
140 $s_action = "editPaste";
141 }
143 /* Create options */
144 if($_POST['menu_action'] == "user_new"){
145 $s_action = "new";
146 }
147 if($_POST['menu_action'] == "user_tplnew"){
148 $s_action = "new_tpl";
149 }
150 if($_POST['menu_action'] == "multiple_edit"){
151 $s_action = "multiple_edit";
152 }
154 /* handle remove from layers menu */
155 if(preg_match("/^multiple_password_change/",$_POST['menu_action'])){
156 $s_action = "multiple_password_change";
157 }
159 /* handle remove from layers menu */
160 if(preg_match("/^remove_multiple/",$_POST['menu_action'])){
161 $s_action = "del_multiple";
162 }
163 if(preg_match("/^templatize_multiple/",$_POST['menu_action'])){
164 $s_action = "templatize_multiple";
165 }
167 if(preg_match("/^event/",$_POST['menu_action'])){
168 $s_action = $_POST['menu_action'];
169 }
170 }
172 /* Use template */
173 if(isset($_POST['templatize_continue'])){
174 $s_action = "templatize_continue";
175 }
178 /********************
179 Create notification event
180 ********************/
182 if(preg_match("/^event_/",$s_action) && class_available("DaemonEvent")){
183 $ids = $this->list_get_selected_items();
184 $uids = array();
185 foreach($ids as $id){
186 $uids[] = $this->list[$id]['uid'][0];
187 }
188 if(count($uids)){
189 $events = DaemonEvent::get_event_types(USER_EVENT);
190 $event = preg_replace("/^event_/","",$s_action);
191 if(isset($events['BY_CLASS'][$event])){
192 $type = $events['BY_CLASS'][$event];
193 $this->usertab = new $type['CLASS_NAME']($this->config);
194 $this->usertab->add_users($uids);
195 $this->usertab->set_type(SCHEDULED_EVENT);
196 }
197 }
198 }
200 /* Abort event dialog */
201 if(isset($_POST['abort_event_dialog'])){
202 $this->usertab = FALSE;
203 }
205 /* Save event */
206 if(isset($_POST['save_event_dialog'])){
207 $this->usertab->save_object();
208 $msgs = $this->usertab->check();
209 if(count($msgs)){
210 msg_dialog::displayChecks($msgs);
211 }else{
213 $o_queue = new gosaSupportDaemon();
214 $o_queue->append($this->usertab);
215 if($o_queue->is_error()){
216 msg_dialog::display(_("Infrastructure error"), msgPool::siError($o_queue->get_error()),ERROR_DIALOG);
217 }else{
218 $this->usertab = FALSE;
219 }
220 }
221 }
223 /* Display event */
224 if($this->usertab instanceof DaemonEvent){
225 $this->usertab->save_object();
226 return($this->usertab->execute());
227 }
230 /********************
231 Copy & Paste
232 ********************/
234 /* Display the copy & paste dialog, if it is currently open */
235 if($this->CPPasswordChange == ""){
236 $ret = $this->copyPasteHandling_from_queue($s_action,$s_entry);
237 if($ret){
238 return($ret);
239 }
240 }
243 /********************
244 Change password confirmed
245 ********************/
247 /* Perform password change */
248 if (isset($_POST['password_finish'])){
250 /* For security reasons, check if user is allowed to set password again */
251 $dn = $this->dn;
252 $acl = $this->ui->get_permissions($dn, "users/password");
253 $cacl= $this->ui->get_permissions($dn, "users/user");
255 /* Are we allowed to create a new user or to set the password attribute? */
256 if (preg_match('/w/', $acl) || preg_match('/c/', $cacl)){
258 /* Check input and feed errors into 'message' */
259 $message= array();
261 /* Sanity checks... */
262 if ($_POST['new_password'] != $_POST['repeated_password']){
264 /* Matching passwords in new and repeated? */
265 $message[]= _("The passwords you've entered as 'New password' and 'Repeated new password' do not match.");
266 } else {
268 /* Empty password is not permitted by default. */
269 if ($_POST['new_password'] == ""){
270 msgPool::required(_("New password"));
271 }
272 }
274 /* Errors, or password change? */
275 if (count($message) != 0){
277 /* Show error message and continue editing */
278 msg_dialog::displayChecks($message);
279 return($smarty->fetch(get_template_path('password.tpl', TRUE)));
280 }
282 $config= $this->config;
283 $ldap_ui= $this->config->get_ldap_link();
284 if(isset($this->usertab->dn)){
285 $ldap_ui->cat($this->usertab->dn,array("uid"));
286 $user = $ldap_ui->fetch();
287 }else{
288 $ldap_ui->cat($this->dn,array("uid"));
289 $user = $ldap_ui->fetch();
290 }
291 if((is_array($user))&&(isset($user['uid']))){
292 $username= $user['uid'][0];
293 }
295 /* Set password, perform required steps */
296 if ($this->usertab){
297 if ($this->usertab->password_change_needed()){
298 $obj= $this->usertab->by_object['user'];
299 if(!change_password ($this->usertab->dn, $_POST['new_password'],0, $obj->pw_storage)){
300 return($smarty->fetch(get_template_path('password.tpl', TRUE)));
301 }
302 if ($config->get_cfg_value("passwordHook") != ""){
303 exec($config->get_cfg_value("passwordHook")." ".$username." ".$_POST['new_password'], $resarr);
304 }
305 new log("modify","users/".get_class($this),$this->usertab->dn,array(),"Password has been changed");
306 unset($this->usertab);
307 $this->usertab= NULL;
308 }
309 } else {
310 if(!change_password ($this->dn, $_POST['new_password'])){
311 return($smarty->fetch(get_template_path('password.tpl', TRUE)));
312 }
313 if ($config->get_cfg_value("passwordHook") != ""){
314 exec($config->get_cfg_value("passwordHook")." ".$username." ".$_POST['new_password'], $resarr);
315 }
316 new log("modify","users/".get_class($this),$this->dn,array(),"Password has been changed");
317 }
318 } else {
320 /* Missing permissions, show message */
321 msg_dialog::display(_("Password change"),_("You have no permission to change this users password!"),WARNING_DIALOG);
322 }
323 /* Clean session, delete lock */
324 $this->remove_lock();
325 unset ($this->usertab);
326 $this->usertab= NULL;
327 $this->lognames= array();;
328 $this->sn= "";
329 $this->givenName= "";
330 $this->uid= "";
331 set_object_info();
332 }
335 /********************
336 Change multiple passwords requested
337 ********************/
339 if($s_action == "multiple_password_change"){
340 $this->pwd_change_queue = $this->list_get_selected_items();
341 $disallowed = array();
342 foreach($this->pwd_change_queue as $key => $id){
343 if(!preg_match("/w/",$this->ui->get_permissions($this->list[trim($id)]['dn'],"users/password"))){
344 unset($this->pwd_change_queue[$key]);
345 $disallowed[] = $this->list[trim($id)]['dn'];
346 }
347 }
348 if(count($disallowed)){
349 msg_dialog::display(_("Permission"),msgPool::permModify($disallowed),INFO_DIALOG);
350 }
351 }
354 /********************
355 Change password requested
356 ********************/
358 /* Password change requested */
359 if (($s_action == "change_pw") || (!empty($this->CPPasswordChange)) || count($this->pwd_change_queue)){
361 /* Get users whose passwords should be changed. */
362 if(count($this->pwd_change_queue)){
363 $s_entry= array_pop($this->pwd_change_queue);
364 }
366 if(!empty($this->CPPasswordChange)){
367 $s_entry = $this->CPPasswordChange;
368 $this->CPPasswordChange = "";
369 }
371 /* Get 'dn' from posted 'uid' */
372 $this->dn= $this->list[trim($s_entry)]['dn'];
374 /* Load permissions for selected 'dn' and check if
375 we're allowed to remove this 'dn' */
376 if (preg_match("/w/",$this->ui->get_permissions($this->dn,"users/password"))){
378 /* User is allowed to change passwords, save 'dn' and 'acl' for next
379 dialog. */
380 set_object_info($this->dn);
381 return ($smarty->fetch(get_template_path('password.tpl', TRUE)));
382 } else {
383 /* User is not allowed. Show message and cancel. */
384 msg_dialog::display(_("Password change"),_("You have no permission to change this users password!"),WARNING_DIALOG);
385 }
386 }
390 /********************
391 Edit existing entry
392 ********************/
395 /* User wants to edit data? */
396 if (($s_action=="edit") && (!isset($this->usertab->config))){
398 /* Get 'dn' from posted 'uid', must be unique */
399 $this->dn= $this->list[trim($s_entry)]['dn'];
401 /* Check locking, save current plugin in 'back_plugin', so
402 the dialog knows where to return. */
404 if (($user= get_lock($this->dn)) != ""){
405 return(gen_locked_message ($user, $this->dn,TRUE));
406 }
408 /* Lock the current entry, so everyone will get the
409 above dialog */
410 add_lock ($this->dn, $this->ui->dn);
412 /* Register usertab to trigger edit dialog */
413 $this->usertab= new usertabs($this->config,
414 $this->config->data['TABS']['USERTABS'], $this->dn);
416 /* Switch tab, if it was requested by the user */
417 $this->usertab->current = $s_tab;
419 /* Set ACL and move DN to the headline */
420 $this->usertab->set_acl_base($this->dn);
421 set_object_info($this->dn);
422 }
425 /********************
426 Edit multiple entries
427 ********************/
429 /* User wants to edit data? */
430 if ($s_action == "multiple_edit" && !isset($this->usertab->config)){
432 $this->dn = array();
433 foreach($this->list_get_selected_items() as $id){
434 $this->dn[] = $this->list[$id]['dn'];;
435 }
436 $tmp = new multi_plug($this->config,"usertabs",$this->config->data['TABS']['USERTABS'],
437 $this->dn,$this->DivListUsers->selectedBase,"user");
438 if ($tmp->entries_locked()){
439 return($tmp->display_lock_message());
440 }
441 $tmp->lock_entries($this->ui->dn);
442 if($tmp->multiple_available()){
443 $this->usertab = $tmp;
444 $this->usertab->set_active_tab($s_tab);
445 set_object_info($this->usertab->get_object_info());
446 }
447 }
450 /********************
451 Edit canceled
452 ********************/
454 /* Reset all relevant data, if we get a _cancel request */
455 if (isset($_POST['edit_cancel']) || isset($_POST['password_cancel'])){
456 if (isset($this->usertab)){
457 $this->remove_lock();
458 }
459 $this->usertab= NULL;
460 $this->lognames= array();;
461 $this->sn= "";
462 $this->givenName= "";
463 $this->uid= "";
464 set_object_info();
465 }
468 /********************
469 We want to create a new user, so fetch all available user templates
470 ********************/
472 /* Generate template list */
473 if ($s_action == "new" || $s_action == "create_user_from_tpl" || $s_action == "templatize_multiple"){
475 $this->templates= array();
476 $ldap= $this->config->get_ldap_link();
478 /* Create list of templates */
479 foreach ($this->config->departments as $key => $value){
481 /* Get acls from different ou's */
482 $acl = $this->ui->get_permissions($value,"users/user") ;
484 /* If creation of a new user is allowed, append this template */
485 if (preg_match("/c/",$acl)){
487 /* Search all templates from the current dn */
488 $ldap->cd (get_people_ou().$value);
489 $ldap->search ("(objectClass=gosaUserTemplate)", array("uid"));
491 /* Append */
492 if ($ldap->count() != 0){
493 while ($attrs= $ldap->fetch()){
494 $this->templates[$ldap->getDN()]=
495 $attrs['uid'][0]." - ".LDAP::fix($key);
496 }
497 if ($s_action != "templatize_multiple"){
498 $this->templates['none']= _("none");
499 }
500 }
501 }
502 }
504 /* Sort templates */
505 natcasesort ($this->templates);
506 reset ($this->templates);
507 }
510 /********************
511 Apply template to multiple entries requested, display confirm dialog
512 ********************/
514 if ($s_action=="templatize_multiple"){
515 $ids = $this->list_get_selected_items();
516 $this->dns = array();
517 if(count($ids)){
519 foreach($ids as $id){
520 $dn = $this->list[$id]['dn'];
521 if (($user= get_lock($dn)) != ""){
522 return(gen_locked_message ($user, $dn));
523 }
524 $this->dns[$id] = $dn;
525 }
526 }
528 $smarty->assign("templates", $this->templates);
530 return($smarty->fetch(get_template_path('templatize.tpl', TRUE)));
531 }
533 /* Perform templatizing after the button has been pressed */
534 if ($s_action == "templatize_continue"){
536 $acl = $this->ui->get_permissions($_POST['template'], "users/user");
538 /* Template readable? */
539 if (preg_match('/r/', $acl)){
540 $template_dn= $_POST['template'];
542 foreach ($this->dns as $dn){
543 $acl = $this->ui->get_permissions($_POST['template'], "users/user");
544 if (preg_match('/w/', $acl)){
545 $usertab= new usertabs($this->config, $this->config->data['TABS']['USERTABS'], $dn);
546 $usertab->adapt_from_template($template_dn, array("sn", "givenName", "uid"));
547 $usertab->save();
548 unset ($usertab);
549 $usertab= NULL;
550 } else {
551 msg_dialog::display(_("Permission error"), sprintf(_("You have no permission to modify object '%s'!"), $dn), ERROR_DIALOG);
552 }
553 }
554 } else {
555 msg_dialog::display(_("Permission error"), _("You have no permission to use this template!"), ERROR_DIALOG);
556 }
558 }
561 /********************
562 Delete MULTIPLE entries requested, display confirm dialog
563 ********************/
565 if ($s_action=="del_multiple" || $s_action == "del"){
567 if($s_action == "del"){
569 /* Get 'dn' from posted 'uid' */
570 $ids = array($s_entry);
571 }else{
572 $ids = $this->list_get_selected_items();
573 }
575 $this->dns = array();
576 if(count($ids)){
577 $disallowed = array();
578 foreach($ids as $id){
579 $dn = $this->list[$id]['dn'];
580 $acl = $this->ui->get_permissions($dn, "users/user");
581 if(preg_match("/d/",$acl)){
582 $this->dns[$id] = $dn;
583 }else{
584 $disallowed[] = $dn;
585 }
586 }
588 if(count($disallowed)){
589 msg_dialog::display(_("Permission"),msgPool::permDelete($disallowed),INFO_DIALOG);
590 }
592 if(count($this->dns)){
594 /* Check locks */
595 if ($user= get_multiple_locks($this->dns)){
596 return(gen_locked_message($user,$this->dns));
597 }
599 $dns_names = array();
600 foreach($this->dns as $dn){
601 $dns_names[] = LDAP::fix($dn);
602 }
604 add_lock($this->dns, $this->ui->dn);
606 /* Lock the current entry, so nobody will edit it during deletion */
607 $info = sprintf(msgPool::deleteInfo($dns_names,_("user")));
609 /* Lock the current entry, so nobody will edit it during deletion */
610 $smarty->assign("info", msgPool::deleteInfo($dns_names));
611 return($smarty->fetch(get_template_path('remove.tpl', TRUE)));
612 }
613 }
614 }
617 /********************
618 Delete MULTIPLE entries confirmed
619 ********************/
621 if(isset($_POST['delete_user_confirm'])){
623 /* Remove user by user and check acls before removeing them */
624 foreach($this->dns as $key => $dn){
626 $acl = $this->ui->get_permissions($dn, "users/user");
627 if (preg_match('/d/', $acl)){
629 /* Delete request is permitted, perform LDAP action */
630 $this->usertab= new usertabs($this->config, $this->config->data['TABS']['USERTABS'],$dn);
631 $this->usertab->set_acl_base();
632 $this->usertab->delete ();
633 unset ($this->usertab);
634 $this->usertab= NULL;
635 } else {
636 msg_dialog::display(_("Warning"),msgPool::permDelete($dn),WARNING_DIALOG);
637 if(isset($this->ui->uid)){
638 new log("security","users/".get_class($this),$dn,array(),"Tried to trick deletion.");
639 }
640 }
641 }
642 /* Remove lock file after successfull deletion */
643 $this->remove_lock();
644 $this->dns = array();
645 }
648 /********************
649 Toggle lock status for user
650 ********************/
652 if($s_action == "toggle_lock_status" && isset($this->list[$s_entry])){
654 /* Get entry check current status */
655 $val = $this->list[$s_entry];
656 if (!preg_match("/w/",$this->ui->get_permissions($val['dn'],"users/password"))){
657 msg_dialog::display(_("Account locking"),
658 _("You have no permission to change the lock status for this user!"),WARNING_DIALOG);
659 }else{
660 $pwd = $val['userPassword'][0];
661 $method = passwordMethod::get_method($pwd,$val['dn']);
662 $success= false;
663 if($method instanceOf passwordMethod){
664 if($method->is_locked($this->config,$val['dn'])){
665 $success= $method->unlock_account($this->config,$val['dn']);
666 }else{
667 $success= $method->lock_account($this->config,$val['dn']);
668 }
670 /* Check for success */
671 if (!$success){
672 $hn= $method->get_hash_name();
673 if (is_array($hn)){
674 $hn= $hn[0];
675 }
676 msg_dialog::display(_("Account locking"),
677 sprintf(_("Password method '%s' does not support locking. Account has not been locked!"), $hn),WARNING_DIALOG);
678 }
679 }else{
680 // Can't lock unknown methods.
681 }
683 }
684 }
686 /********************
687 Delete entry Canceled
688 ********************/
690 /* Delete user canceled? */
691 if (isset($_POST['delete_cancel'])){
693 /* Remove lock file after successfull deletion */
694 $this->remove_lock();
695 $this->dns = array();
696 }
699 /********************
700 Edit entry finished (Save)
701 ********************/
703 /* Finish user edit is triggered by the tabulator dialog, so
704 the user wants to save edited data. Check and save at this
705 point. */
706 if ((isset($_POST['edit_finish']) || isset($_POST['edit_apply'])) && (isset($this->usertab->config))){
708 /* Check tabs, will feed message array */
709 $this->usertab->last= $this->usertab->current;
710 $this->usertab->save_object();
711 $message= $this->usertab->check();
713 /* Save, or display error message? */
714 if (count($message) == 0){
716 /* No errors. Go ahead and prepare to ask for a password
717 in case we're creating a new user. 'dn' will be 'new'
718 in this case. It is set to the correct value later. */
719 if ($this->dn == "new"){
720 $set_pass= 1;
721 } else {
722 $set_pass= 0;
723 }
725 /* Save user data to ldap */
726 if($this->usertab->save() == 1){
727 return;
728 }
730 if (!isset($_POST['edit_apply'])){
731 /* User has been saved successfully, remove lock from LDAP. */
732 if ($this->dn != "new"){
733 $this->remove_lock();
734 }
736 /* In case of new users, ask for a password, skip this for templates */
737 if (($set_pass || $this->usertab->password_change_needed()) && !$this->is_template){
738 $this->dn = $this->usertab->dn;
739 return($smarty->fetch(get_template_path('password.tpl', TRUE)));
740 }
742 unset ($this->usertab);
743 $this->usertab= NULL;
744 set_object_info();
745 }else{
747 /* Reinitialize tab */
748 if($this->usertab instanceof tabs){
749 $this->usertab->re_init();
750 }
751 }
752 } else {
753 /* Ok. There seem to be errors regarding to the tab data,
754 show message and continue as usual. */
755 msg_dialog::displayChecks($message);
756 }
757 }
761 /********************
762 Create a new user,template, user from template
763 ********************/
765 /* Check selected options for template */
766 if (isset($_POST['template_continue'])){
767 $message = array();
768 if(!isset($_POST['template']) || (empty($_POST['template']))){
769 $message[]= msgPool::invalid(_("Template"));
770 }
771 if(!isset($_POST['sn']) || (empty($_POST['sn']))){
772 $message[]= msgPool::required(_("Name"));
773 }
774 if(!isset($_POST['givenName']) || (empty($_POST['givenName']))){
775 $message[]= msgPool::required(_("Given name"));
776 }
778 /* Show error message / continue editing */
779 if (count($message) > 0){
780 msg_dialog::displayChecks($message);
782 foreach(array("sn", "givenName", "uid", "template") as $attr){
783 if(isset($_POST[$attr])){
784 $smarty->assign("$attr", $_POST[$attr]);
785 }else{
786 $smarty->assign("$attr", "");
787 }
788 }
789 $smarty->assign("templates",$this->templates);
790 $smarty->assign("got_uid",$this->got_uid);
791 $smarty->assign("edit_uid",false);
792 return($smarty->fetch(get_template_path('template.tpl', TRUE)));
794 }
795 }
797 /* New user/template request */
798 if (($s_action=="create_user_from_tpl")||($s_action=="new") || ($s_action=="new_tpl")){
799 /* By default we set 'dn' to 'new', all relevant plugins will
800 react on this. */
801 $this->dn= "new";
803 $this->got_uid= ($this->config->get_cfg_value("idGenerator") == "");
805 /* Create new usertab object */
806 $this->usertab= new usertabs($this->config,$this->config->data['TABS']['USERTABS'], $this->dn);
807 $this->usertab->by_object['user']->base= $this->DivListUsers->selectedBase;
808 $this->usertab->set_acl_base($this->DivListUsers->selectedBase);
810 /* Take care about templates */
811 if ($s_action=="new_tpl"){
812 $this->is_template= TRUE;
813 $this->usertab->set_template_mode ();
814 } else {
815 $this->is_template= FALSE;
816 }
818 /* Use template if there are any of them */
819 if ((count($this->templates) && ($s_action!='new_tpl'))||($s_action=="create_user_from_tpl")){
820 foreach(array("sn", "givenName", "uid", "got_uid", "templates") as $attr){
821 $smarty->assign("$attr", $this->$attr);
822 }
823 if ($s_action=="create_user_from_tpl"){
824 $smarty->assign("template", $this->dn= $this->list[trim($s_entry)]['dn']);
825 } else {
826 $smarty->assign("template", "none");
827 }
828 $smarty->assign("edit_uid", "");
829 return($smarty->fetch(get_template_path('template.tpl', TRUE)));
830 }
831 }
833 /********************
834 Template selected continue edit
835 ********************/
837 /* Continue template editing */
838 if ((isset($_POST['template_continue'])) && ($_POST['template'] != 'none') && (!isset($_POST['uid']))){
840 $this->sn = $_POST['sn'];
841 $this->givenName = $_POST['givenName'];
843 /* Check for requred values */
844 $message= array();
845 if ($this->sn == "") {
846 $message[]= msgPool::required(_("Name"));
847 }
848 if ($this->givenName == "") {
849 $message[]= msgPool::required(_("Given name"));
850 }
852 /* Check if dn is used */
853 $dn= preg_replace("/^[^,]+,/i", "", $_POST['template']);
854 $ldap= $this->config->get_ldap_link();
855 $ldap->cd ($dn);
856 $ldap->search ("(&(sn=".normalizeLdap($this->sn).")(givenName=".normalizeLdap($this->givenName)."))", array("givenName"));
857 if ($ldap->count () != 0){
858 msgPool::duplicated(_("Name"));
859 }
861 /* Show error message / continue editing */
862 if (count($message) > 0){
863 msg_dialog::displayChecks($message);
864 } else {
865 $attributes= array('sn' => $this->sn, 'givenName' => $this->givenName);
866 if ($this->config->get_cfg_value("idGenerator") != ""){
867 $uids= gen_uids ($this->config->get_cfg_value("idGenerator"), $attributes);
868 if (count($uids)){
869 $smarty->assign("edit_uid", "false");
870 $smarty->assign("uids", $uids);
871 $this->uid= current($uids);
872 }
873 } else {
874 $smarty->assign("edit_uid", "");
875 $this->uid= "";
876 }
877 $this->got_uid= true;
878 }
880 foreach(array("sn", "givenName", "uid", "got_uid", "templates") as $attr){
881 $smarty->assign("$attr", $this->$attr);
882 }
883 if (isset($_POST['template'])){
884 $smarty->assign("template", $_POST['template']);
885 }
886 return($smarty->fetch(get_template_path('template.tpl', TRUE)));
887 }
889 /********************
890 No template selected continue edit
891 ********************/
893 /* No template. Ok. Lets fill data into the normal user dialog */
894 if (isset($_POST['template_continue']) && $_POST['template'] == 'none'){
895 foreach(array("sn", "givenName", "uid") as $attr){
896 if (isset($_POST[$attr])){
897 $this->usertab->by_object['user']->$attr= $_POST[$attr];
898 }
899 }
900 }
903 /********************
904 Template selected continue edit
905 ********************/
907 /* Finish template preamble */
908 if (isset($_POST['template_continue']) && $_POST['template'] != 'none' && (isset($_POST['uid']))){
910 /* Move user supplied data to sub plugins */
911 foreach(array("uid","sn","givenName") as $attr){
912 $this->$attr = $_POST[$attr];
913 $this->usertab->$attr = $this->$attr;
914 $this->usertab->by_object['user']->$attr = $this->$attr;
915 }
917 $template_dn = $_POST['template'];
918 $this->usertab->adapt_from_template($template_dn, array("uid","cn","givenName","sn"));
919 $template_base = preg_replace("/^[^,]+,".preg_quote(get_people_ou(), '/')."/", '', $template_dn);
920 $this->usertab->by_object['user']->base= $template_base;
921 }
924 /********************
925 If no template was selected set base
926 ********************/
928 if (isset($_POST['template_continue']) && ($_POST['template'] == 'none')){
929 $this->usertab->by_object['user']->base= $this->DivListUsers->selectedBase;
930 }
933 /********************
934 Display subdialog
935 ********************/
937 /* Show tab dialog if object is present */
938 if(isset($this->usertab->config)){
940 $display= $this->usertab->execute();
942 /* Don't show buttons if tab dialog requests this */
944 $dia = FALSE;
945 if(isset($this->usertab->by_object[$this->usertab->current]->dialog)){
946 $dia = $this->usertab->by_object[$this->usertab->current]->dialog;
947 }
949 if(!is_object($dia) && $dia != TRUE){
950 if(($this->usertab instanceOf tabs || $this->usertab instanceOf plugin) && $this->usertab->read_only == TRUE){
951 $display.= "<p style=\"text-align:right\">
952 <input type=submit name=\"edit_cancel\" value=\"".msgPool::cancelButton()."\">
953 </p>";
954 }else{
955 $display.= "<p style=\"text-align:right\">\n";
956 $display.= "<input type=submit name=\"edit_finish\" style=\"width:80px\" value=\"".msgPool::okButton()."\">\n";
957 $display.= " \n";
958 if ($this->dn != "new"){
959 $display.= "<input type=submit name=\"edit_apply\" value=\"".msgPool::applyButton()."\">\n";
960 $display.= " \n";
961 }
962 $display.= "<input type=submit name=\"edit_cancel\" value=\"".msgPool::cancelButton()."\">\n";
963 $display.= "</p>";
964 }
965 }
966 return ($display);
967 }
969 /* Check if there is a snapshot dialog open */
970 $base = $this->DivListUsers->selectedBase;
971 if($str = $this->showSnapshotDialog($base,$this->get_used_snapshot_bases(),$this)){
972 return($str);
973 }
975 /* Return rendered main page */
976 $this->DivListUsers->parent = $this;
977 $this->DivListUsers->execute();
979 /* Add departments if subsearch is disabled */
980 if(!$this->DivListUsers->SubSearch){
981 $this->DivListUsers->AddDepartments($this->DivListUsers->selectedBase,4,1);
982 }
983 $this->reload();
984 $this->DivListUsers->setEntries($this->list);
986 # FILTER Test #################################################
987 ## Build filter
988 #if (!$this->filter) {
989 # $this->filter = new filter(get_template_path("user-filter.xml", true));
990 # $this->filter->setObjectStorage(get_people_ou());
991 #}
992 #$this->filter->update();
993 #session::set('autocomplete', $this->filter);
994 #if (!$this->filter->isValid()){
995 # msg_dialog::display(_("Filter error"), _("The filter is uncomplete!"), ERROR_DIALOG);
996 #}
998 ## Build headpage
999 #if (!$this->headpage){
1000 # $this->headpage = new listing(get_template_path("user-list.xml", true));
1001 # $this->headpage->registerElementFilter("accountProperties", "userManagement::filterProperties");
1002 # $this->headpage->registerElementFilter("lockLabel", "userManagement::filterLockLabel");
1003 # $this->headpage->registerElementFilter("lockImage", "userManagement::filterLockImage");
1004 # $this->headpage->setFilter($this->filter);
1005 #}
1007 ## Needs to be called before update!
1008 #$action= $this->headpage->getAction();
1009 #if ($action['action'] != '') {
1010 # echo "List detected action:";
1011 # print_a($action);
1012 #}
1014 ## Refresh for filter
1015 #$this->headpage->update();
1016 #
1017 #return($this->headpage->render());
1018 ################################################### FILTER Test
1020 return($this->DivListUsers->Draw());
1021 }
1024 static function filterLockImage($userPassword)
1025 {
1026 $image= "images/empty.png";
1028 if(isset($userPassword[0]) && preg_match("/^\{[^\}]/",$userPassword[0])){
1029 if(preg_match("/^[^\}]*+\}!/",$userPassword[0])){
1030 $image= "images/lists/locked.png";
1031 }else{
1032 $image= "images/lists/unlocked.png";
1033 }
1034 }
1036 return $image;
1037 }
1040 static function filterLockLabel($userPassword)
1041 {
1042 $label= "";
1044 if(isset($userPassword[0]) && preg_match("/^\{[^\}]/",$userPassword[0])){
1045 if(preg_match("/^[^\}]*+\}!/",$userPassword[0])){
1046 $label= _("Unlock account");
1047 }else{
1048 $label= _("Lock account");
1049 }
1050 }
1052 return $label;
1053 }
1056 static function filterProperties($dn, $row, $class)
1057 {
1058 $result= "";
1060 $map= array( "gosaAccount" => array( "image" => "plugins/users/images/select_user.png",
1061 "plugin" => "user",
1062 "alt" => _("Generic"),
1063 "title" => _("Edit generic properties")),
1064 "posixAccount" => array("image" => "images/penguin.png",
1065 "plugin" => "posixAccount",
1066 "alt" => _("POSIX"),
1067 "title" => _("Edit POSIX properties")),
1068 "gosaMailAccount" => array("image" => "images/mailto.png",
1069 "alt" => _("Mail"),
1070 "plugin" => "mailAccount",
1071 "title" => _("Edit mail properties")),
1072 "sambaSamAccount" => array("image" => "plugins/systems/images/select_winstation.png",
1073 "plugin" => "sambaAccount",
1074 "alt" => _("Samba"),
1075 "title" => _("Edit samba properties")),
1076 "apple-user" => array("image" => "plugins/netatalk/images/select_netatalk.png",
1077 "plugin" => "sambaAccount",
1078 "alt" => _("Netatalk"),
1079 "title" => _("Edit netatalk properties")),
1080 "gotoEnvironment" => array("image" => "plugins/users/images/small_environment.png",
1081 "plugin" => "gotoEnvironment",
1082 "alt" => _("Environment"),
1083 "title" => _("Edit environment properties")),
1084 "goFaxAccount" => array("image" => "plugins/users/images/fax_small.png",
1085 "plugin" => "goFaxAccount",
1086 "alt" => _("FAX"),
1087 "title" => _("Edit FAX properties")),
1088 "goFonAccount" => array("image" => "plugins/gofon/images/select_phone.png",
1089 "plugin" => "goFonAccount",
1090 "alt" => _("Phone"),
1091 "title" => _("Edit phone properties")));
1093 // Walk thru map
1094 foreach ($map as $oc => $properties) {
1095 if (in_array($oc, $class)) {
1096 $result.="<input class='center' type='image' src='".$properties['image']."' ".
1097 "alt='".$properties['alt']."' title='".$properties['title'].
1098 "' name='listing_edit_".$properties['plugin']."_$row' style='padding:1px'>";
1099 } else {
1100 $result.="<img src='images/empty.png' alt=' ' class='center' style='padding:1px'>";
1101 }
1102 }
1104 return $result;
1105 }
1109 /* Return departments, that will be included within snapshot detection */
1110 function get_used_snapshot_bases()
1111 {
1112 return(array(get_people_ou().$this->DivListUsers->selectedBase));
1113 }
1116 function reload()
1117 {
1118 /* Set base for all searches */
1119 $base= $this->DivListUsers->selectedBase;
1120 $this->list =array();
1122 /* Get filter configuration */
1123 $Regex = $this->DivListUsers->Regex;
1124 $SubSearch = $this->DivListUsers->SubSearch;
1125 $ShowTemplates = $this->DivListUsers->ShowTemplates;
1126 $ShowFunctionalUsers = $this->DivListUsers->ShowFunctionalUsers;
1127 $ShowUnixUsers = $this->DivListUsers->ShowUnixUsers;
1128 $ShowMailUsers = $this->DivListUsers->ShowMailUsers;
1129 $ShowSambaUsers = $this->DivListUsers->ShowSambaUsers;
1130 $ShowProxyUsers = $this->DivListUsers->ShowProxyUsers;
1132 /* Setup filter depending on selection */
1133 $filter="";
1134 if ($this->config->get_cfg_value("sambaversion") == 3){
1135 $samba= "sambaSamAccount";
1136 } else {
1137 $samba= "sambaAccount";
1138 }
1140 if ($ShowFunctionalUsers){
1141 $filter.= "(&(objectClass=gosaAccount)(!(|(objectClass=posixAccount)".
1142 "(objectClass=gosaMailAccount)(objectClass=$samba)".
1143 "(objectClass=gosaProxyAccount))))";
1144 }
1145 if ($ShowUnixUsers){
1146 $filter.= "(objectClass=posixAccount)";
1147 }
1148 if ($ShowMailUsers){
1149 $filter.= "(objectClass=gosaMailAccount)";
1150 }
1151 if ($ShowSambaUsers){
1152 $filter.= "(objectClass=$samba)";
1153 }
1154 if ($ShowProxyUsers){
1155 $filter.= "(objectClass=gosaProxyAccount)";
1156 }
1157 if ($ShowTemplates){
1158 $filter= "(|(objectClass=gosaUserTemplate)(&(objectClass=gosaAccount)(|$filter)))";
1159 } else {
1160 $filter= "(&(objectClass=gosaAccount)(objectClass=person)".
1161 "(objectClass=inetOrgPerson)(objectClass=organizationalPerson)".
1162 "(!(objectClass=gosaUserTemplate))(|$filter))";
1163 }
1164 $filter= "(&(|(uid=".normalizeLdap($Regex).")(sn=".normalizeLdap($Regex).")(givenName=".normalizeLdap($Regex)."))$filter)";
1166 /* Generate userlist */
1167 $ldap= $this->config->get_ldap_link(TRUE);
1169 if ($SubSearch){
1170 $ListTemp = get_sub_list($filter, "users", get_people_ou(),$base,
1171 array("uid", "givenName", "sn", "objectClass","userPassword"), GL_SUBSEARCH | GL_SIZELIMIT);
1172 } else {
1173 $base= get_people_ou().$base;
1174 $ListTemp = get_sub_list($filter, "users", get_people_ou(),$base,
1175 array("uid", "givenName", "sn", "objectClass","userPassword"), GL_SIZELIMIT);
1176 }
1177 $SortTemp = array();
1178 $List = array();
1180 foreach($ListTemp as $Key => $Entry){
1182 /* Due to the fact that "inetOrgPerson" is derived from "organizationalPerson" and that openldap
1183 doesn't differentiate both classes in search filters, we have to skip entries that do not provide
1184 both classes. (Both classes are required for a valid GOsa user Account.)
1185 */
1186 if(!in_array("inetOrgPerson",$Entry['objectClass'])|| !in_array("organizationalPerson",$Entry['objectClass'])){
1187 continue;
1188 }
1190 /* Skip entries that are not located under the people ou (normaly 'ou=people,')
1191 * Else winstations will be listed too, if you use the subtree flag.
1192 */
1193 if(!preg_match("/".preg_quote(get_people_ou(), '/')."/i",$Entry['dn'])){
1194 continue;
1195 }else{
1197 // Generate caption for rows
1198 if (isset($Entry["sn"]) && isset($Entry["givenName"])){
1199 $display= $Entry["sn"][0].", ".$Entry["givenName"][0]." [".$Entry["uid"][0]."]";
1200 } else {
1201 $display= "[".$Entry["uid"][0]."]";
1202 }
1204 $display = strtolower($display);
1205 $List[$display] = $Entry;
1206 $SortTemp[$display] = $display;
1207 }
1208 }
1209 natcasesort($SortTemp);
1210 reset($SortTemp);
1212 $this->list = array();
1213 foreach($SortTemp as $Key){
1214 $this->list[] = $List[$Key];
1215 }
1216 }
1219 function remove_lock()
1220 {
1221 /* Remove user lock if a DN is marked as "currently edited" */
1222 if (isset($this->usertab->dn)){
1223 del_lock ($this->usertab->dn);
1224 }elseif(isset($this->dn) && !empty($this->dn) && $this->dn != "new"){
1225 del_lock($this->dn);
1226 }
1227 if(isset($this->dns) && is_array($this->dns) && count($this->dns)){
1228 del_lock($this->dns);
1229 }
1230 }
1233 function copyPasteHandling_from_queue($s_action,$s_entry)
1234 {
1235 /* Check if Copy & Paste is disabled */
1236 if(!is_object($this->CopyPasteHandler)){
1237 return("");
1238 }
1240 $ui = get_userinfo();
1242 /* Add a single entry to queue */
1243 if($s_action == "cut" || $s_action == "copy"){
1245 /* Cleanup object queue */
1246 $this->CopyPasteHandler->cleanup_queue();
1247 $dn = $this->list[$s_entry]['dn'];
1248 if($s_action == "copy" && $ui->is_copyable($dn,"users","user")){
1249 $this->CopyPasteHandler->add_to_queue($dn,$s_action,"usertabs","USERTABS","users");
1250 }
1251 if($s_action == "cut" && $ui->is_cutable($dn,"users","user")){
1252 $this->CopyPasteHandler->add_to_queue($dn,$s_action,"usertabs","USERTABS","users");
1253 }
1254 }
1256 /* Add entries to queue */
1257 if($s_action == "copy_multiple" || $s_action == "cut_multiple"){
1259 /* Cleanup object queue */
1260 $this->CopyPasteHandler->cleanup_queue();
1262 /* Add new entries to CP queue */
1263 foreach($this->list_get_selected_items() as $id){
1264 $dn = $this->list[$id]['dn'];
1266 if($s_action == "copy_multiple" && $ui->is_copyable($dn,"users","user")){
1267 $this->CopyPasteHandler->add_to_queue($dn,"copy","usertabs","USERTABS","users");
1268 }
1269 if($s_action == "cut_multiple" && $ui->is_cutable($dn,"users","user")){
1270 $this->CopyPasteHandler->add_to_queue($dn,"cut","usertabs","USERTABS","users");
1271 }
1272 }
1273 }
1275 /* Start pasting entries */
1276 if($s_action == "editPaste"){
1277 $this->start_pasting_copied_objects = TRUE;
1278 }
1280 /* Return C&P dialog */
1281 if($this->start_pasting_copied_objects && $this->CopyPasteHandler->entries_queued()){
1283 /* Get dialog */
1284 $this->CopyPasteHandler->SetVar("base",$this->DivListUsers->selectedBase);
1285 $data = $this->CopyPasteHandler->execute();
1287 /* Set CPPasswordChange to s_entry which indicates that this entry requires a new password. */
1288 if(isset($_POST['passwordTodo']) && ($_POST['passwordTodo'] == "new")){
1289 $s_entry = $this->CopyPasteHandler->last_entry();
1290 $this->reload();
1291 foreach($this->list as $key => $entry){
1292 if($entry['dn'] == $s_entry){
1293 $this->CPPasswordChange = $key;
1294 }
1295 }
1296 }
1298 /* Return dialog data */
1299 if(!empty($data) && $this->CPPasswordChange == ""){
1300 return($data);
1301 }
1302 }
1304 /* Automatically disable status for pasting */
1305 if(!$this->CopyPasteHandler->entries_queued()){
1306 $this->start_pasting_copied_objects = FALSE;
1307 }
1308 return("");
1309 }
1312 function save_object()
1313 {
1314 /* Handle divlist filter && department selection*/
1315 if(!is_object($this->usertab)){
1316 $this->DivListUsers->save_object();
1317 }
1318 if(is_object($this->CopyPasteHandler)){
1319 $this->CopyPasteHandler->save_object();
1320 }
1321 }
1324 function list_get_selected_items()
1325 {
1326 $ids = array();
1327 foreach($_POST as $name => $value){
1328 if(preg_match("/^item_selected_[0-9]*$/",$name)){
1329 $id = preg_replace("/^item_selected_/","",$name);
1330 $ids[$id] = $id;
1331 }
1332 }
1333 return($ids);
1334 }
1337 /* A set of disabled and therefore overloaded functions. They are
1338 not needed in this class. */
1339 function remove_from_parent() { }
1340 function check() { }
1341 function save() { }
1342 function adapt_from_template($dn, $skip= array()) { }
1343 function password_change_needed() { }
1345 } /* ... class userManagement */
1346 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1347 ?>