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 $SnapshotHandler = NULL;
37 var $CPPasswordChange = ""; // Contains the entry id which should get a new password
38 var $DivListUsers;
40 var $pwd_change_queue = array();
42 var $start_pasting_copied_objects = FALSE;
43 var $msg_dialog= NULL;
44 var $acl_module = array("users");
45 var $dns = array();
47 // Filter/headpage tests
48 var $filter= null;
49 var $headpage= null;
52 function userManagement(&$config, $ui)
53 {
54 /* Save configuration for internal use */
55 $this->config= &$config;
56 $this->ui= &$ui;
58 /* Copy & Paste handler */
59 if ($this->config->boolValueIsTrue("main", "copyPaste")){
60 $this->CopyPasteHandler= new CopyPasteHandler($this->config);
61 }
62 if($this->config->get_cfg_value("enableSnapshots") == "true"){
63 $this->SnapshotHandler= new SnapshotHandler($this->config);
64 }
66 /* Creat dialog object */
67 $this->DivListUsers = new divListUsers($this->config,$this);
69 }
72 function execute()
73 {
74 /* Call parent execute */
75 plugin::execute();
77 /* LOCK MESSAGE Vars */
78 session::set('LOCK_VARS_TO_USE',array("/^act$/","/^id$/","/^user_edit_/","/^user_del_/","/^item_selected/","/^remove_multiple_users/","/^multiple_edit/","/menu_action/"));
80 $smarty = get_smarty(); // Smarty instance
81 $s_action = ""; // Contains the action to be taken
82 $s_entry = ""; // The value for s_action
84 /* Edit entry button pressed? */
85 if( isset($_GET['act']) && $_GET['act'] == "edit_entry" ){
86 $s_action= "edit";
87 $s_entry= validate($_GET['id']);
88 }
90 /* Test relevant POST values */
91 foreach($_POST as $key => $val){
93 /* Get every possible POST combination and set s_action/s_entry accordingly */
94 foreach(array("del" => "user_del",
95 "edit" => "user_edit",
96 "new" => "user_new",
97 "new_tpl" => "user_tplnew",
98 "del_multiple" => "^remove_multiple_users",
99 "create_user_from_tpl" => "userfrom_tpl",
100 "change_pw" => "user_chgpw",
101 "editPaste" => "editPaste",
102 "copy_multiple" => "multiple_copy_users",
103 "multiple_edit" => "multiple_edit",
104 "cut_multiple" => "multiple_cut_users",
105 "multiple_password_change" => "multiple_password_change",
106 "copy" => "^copy",
107 "toggle_lock_status" => "toggle_lock_status",
108 "cut" => "^cut") as $act => $name){
110 if (preg_match("/".$name.".*/", $key)){
111 $s_action= $act;
112 $s_entry= preg_replace("/".$name."_/i", "", $key);
113 break;
114 }
115 }
117 } /* ...Test POST */
119 /* Remove coordinate prefix from POST, required by some browsers */
120 $s_entry= preg_replace("/_.$/", "", $s_entry);
122 /* Seperate possibly encoded tab and entry, default to tab "user" */
123 if(preg_match("/.*-.*/", $s_entry)){
124 $s_tab= preg_replace("/^[^-]*-/i", "" ,$s_entry);
125 $s_entry= preg_replace("/-[^-]*$/i", "", $s_entry);
126 }else{
127 $s_tab= "user";
128 }
130 if(!$this->config->search($s_tab, 'class',array('tabs'))){
131 $s_tab = "user";
132 }
134 if (isset($_POST['menu_action'])){
136 /* handle C&P from layers menu */
137 if(preg_match("/^multiple_copy_systems/",$_POST['menu_action'])){
138 $s_action = "copy_multiple";
139 }
140 if(preg_match("/^multiple_cut_systems/",$_POST['menu_action'])){
141 $s_action = "cut_multiple";
142 }
143 if(preg_match("/^editPaste/",$_POST['menu_action'])){
144 $s_action = "editPaste";
145 }
147 /* Create options */
148 if($_POST['menu_action'] == "user_new"){
149 $s_action = "new";
150 }
151 if($_POST['menu_action'] == "user_tplnew"){
152 $s_action = "new_tpl";
153 }
154 if($_POST['menu_action'] == "multiple_edit"){
155 $s_action = "multiple_edit";
156 }
158 /* handle remove from layers menu */
159 if(preg_match("/^multiple_password_change/",$_POST['menu_action'])){
160 $s_action = "multiple_password_change";
161 }
163 /* handle remove from layers menu */
164 if(preg_match("/^remove_multiple/",$_POST['menu_action'])){
165 $s_action = "del_multiple";
166 }
167 if(preg_match("/^templatize_multiple/",$_POST['menu_action'])){
168 $s_action = "templatize_multiple";
169 }
171 if(preg_match("/^event/",$_POST['menu_action'])){
172 $s_action = $_POST['menu_action'];
173 }
174 }
176 /* Use template */
177 if(isset($_POST['templatize_continue'])){
178 $s_action = "templatize_continue";
179 }
182 /********************
183 Create notification event
184 ********************/
186 if(preg_match("/^event_/",$s_action) && class_available("DaemonEvent")){
187 $ids = $this->list_get_selected_items();
188 $uids = array();
189 foreach($ids as $id){
190 $uids[] = $this->list[$id]['uid'][0];
191 }
192 if(count($uids)){
193 $events = DaemonEvent::get_event_types(USER_EVENT);
194 $event = preg_replace("/^event_/","",$s_action);
195 if(isset($events['BY_CLASS'][$event])){
196 $type = $events['BY_CLASS'][$event];
197 $this->usertab = new $type['CLASS_NAME']($this->config);
198 $this->usertab->add_users($uids);
199 $this->usertab->set_type(SCHEDULED_EVENT);
200 }
201 }
202 }
204 /* Abort event dialog */
205 if(isset($_POST['abort_event_dialog'])){
206 $this->usertab = FALSE;
207 }
209 /* Save event */
210 if(isset($_POST['save_event_dialog'])){
211 $this->usertab->save_object();
212 $msgs = $this->usertab->check();
213 if(count($msgs)){
214 msg_dialog::displayChecks($msgs);
215 }else{
217 $o_queue = new gosaSupportDaemon();
218 $o_queue->append($this->usertab);
219 if($o_queue->is_error()){
220 msg_dialog::display(_("Infrastructure error"), msgPool::siError($o_queue->get_error()),ERROR_DIALOG);
221 }else{
222 $this->usertab = FALSE;
223 }
224 }
225 }
227 /* Display event */
228 if($this->usertab instanceof DaemonEvent){
229 $this->usertab->save_object();
230 return($this->usertab->execute());
231 }
234 /********************
235 Copy & Paste
236 ********************/
238 /* Display the copy & paste dialog, if it is currently open */
239 if($this->CPPasswordChange == ""){
240 $ret = $this->copyPasteHandling_from_queue($s_action,$s_entry);
241 if($ret){
242 return($ret);
243 }
244 }
247 /********************
248 Change password confirmed
249 ********************/
251 /* Perform password change */
252 if (isset($_POST['password_finish'])){
254 /* For security reasons, check if user is allowed to set password again */
255 $dn = $this->dn;
256 $acl = $this->ui->get_permissions($dn, "users/password");
257 $cacl= $this->ui->get_permissions($dn, "users/user");
259 /* Are we allowed to create a new user or to set the password attribute? */
260 if (preg_match('/w/', $acl) || preg_match('/c/', $cacl)){
262 /* Check input and feed errors into 'message' */
263 $message= array();
265 /* Sanity checks... */
266 if ($_POST['new_password'] != $_POST['repeated_password']){
268 /* Matching passwords in new and repeated? */
269 $message[]= _("The passwords you've entered as 'New password' and 'Repeated new password' do not match.");
270 } else {
272 /* Empty password is not permitted by default. */
273 if ($_POST['new_password'] == ""){
274 msgPool::required(_("New password"));
275 }
276 }
278 /* Errors, or password change? */
279 if (count($message) != 0){
281 /* Show error message and continue editing */
282 msg_dialog::displayChecks($message);
283 return($smarty->fetch(get_template_path('password.tpl', TRUE)));
284 }
286 $config= $this->config;
287 $ldap_ui= $this->config->get_ldap_link();
288 if(isset($this->usertab->dn)){
289 $ldap_ui->cat($this->usertab->dn,array("uid"));
290 $user = $ldap_ui->fetch();
291 }else{
292 $ldap_ui->cat($this->dn,array("uid"));
293 $user = $ldap_ui->fetch();
294 }
295 if((is_array($user))&&(isset($user['uid']))){
296 $username= $user['uid'][0];
297 }
299 /* Set password, perform required steps */
300 if ($this->usertab){
301 if ($this->usertab->password_change_needed()){
302 $obj= $this->usertab->by_object['user'];
303 if(!change_password ($this->usertab->dn, $_POST['new_password'],0, $obj->pw_storage)){
304 return($smarty->fetch(get_template_path('password.tpl', TRUE)));
305 }
306 if ($config->get_cfg_value("passwordHook") != ""){
307 exec($config->get_cfg_value("passwordHook")." ".$username." ".$_POST['new_password'], $resarr);
308 }
309 new log("modify","users/".get_class($this),$this->usertab->dn,array(),"Password has been changed");
310 unset($this->usertab);
311 $this->usertab= NULL;
312 }
313 } else {
314 if(!change_password ($this->dn, $_POST['new_password'])){
315 return($smarty->fetch(get_template_path('password.tpl', TRUE)));
316 }
317 if ($config->get_cfg_value("passwordHook") != ""){
318 exec($config->get_cfg_value("passwordHook")." ".$username." ".$_POST['new_password'], $resarr);
319 }
320 new log("modify","users/".get_class($this),$this->dn,array(),"Password has been changed");
321 }
322 } else {
324 /* Missing permissions, show message */
325 msg_dialog::display(_("Password change"),_("You have no permission to change this users password!"),WARNING_DIALOG);
326 }
327 /* Clean session, delete lock */
328 $this->remove_lock();
329 unset ($this->usertab);
330 $this->usertab= NULL;
331 $this->lognames= array();;
332 $this->sn= "";
333 $this->givenName= "";
334 $this->uid= "";
335 set_object_info();
336 }
339 /********************
340 Change multiple passwords requested
341 ********************/
343 if($s_action == "multiple_password_change"){
344 $this->pwd_change_queue = $this->list_get_selected_items();
345 $disallowed = array();
346 foreach($this->pwd_change_queue as $key => $id){
347 if(!preg_match("/w/",$this->ui->get_permissions($this->list[trim($id)]['dn'],"users/password"))){
348 unset($this->pwd_change_queue[$key]);
349 $disallowed[] = $this->list[trim($id)]['dn'];
350 }
351 }
352 if(count($disallowed)){
353 msg_dialog::display(_("Permission"),msgPool::permModify($disallowed),INFO_DIALOG);
354 }
355 }
358 /********************
359 Change password requested
360 ********************/
362 /* Password change requested */
363 if (($s_action == "change_pw") || (!empty($this->CPPasswordChange)) || count($this->pwd_change_queue)){
365 /* Get users whose passwords should be changed. */
366 if(count($this->pwd_change_queue)){
367 $s_entry= array_pop($this->pwd_change_queue);
368 }
370 if(!empty($this->CPPasswordChange)){
371 $s_entry = $this->CPPasswordChange;
372 $this->CPPasswordChange = "";
373 }
375 /* Get 'dn' from posted 'uid' */
376 $this->dn= $this->list[trim($s_entry)]['dn'];
378 /* Load permissions for selected 'dn' and check if
379 we're allowed to remove this 'dn' */
380 if (preg_match("/w/",$this->ui->get_permissions($this->dn,"users/password"))){
382 /* User is allowed to change passwords, save 'dn' and 'acl' for next
383 dialog. */
384 set_object_info($this->dn);
385 return ($smarty->fetch(get_template_path('password.tpl', TRUE)));
386 } else {
387 /* User is not allowed. Show message and cancel. */
388 msg_dialog::display(_("Password change"),_("You have no permission to change this users password!"),WARNING_DIALOG);
389 }
390 }
394 /********************
395 Edit existing entry
396 ********************/
399 /* User wants to edit data? */
400 if (($s_action=="edit") && (!isset($this->usertab->config))){
402 /* Get 'dn' from posted 'uid', must be unique */
403 $this->dn= $this->list[trim($s_entry)]['dn'];
405 /* Check locking, save current plugin in 'back_plugin', so
406 the dialog knows where to return. */
408 if (($user= get_lock($this->dn)) != ""){
409 return(gen_locked_message ($user, $this->dn,TRUE));
410 }
412 /* Lock the current entry, so everyone will get the
413 above dialog */
414 add_lock ($this->dn, $this->ui->dn);
416 /* Register usertab to trigger edit dialog */
417 $this->usertab= new usertabs($this->config,
418 $this->config->data['TABS']['USERTABS'], $this->dn);
420 /* Switch tab, if it was requested by the user */
421 $this->usertab->current = $s_tab;
423 /* Set ACL and move DN to the headline */
424 $this->usertab->set_acl_base($this->dn);
425 set_object_info($this->dn);
426 }
429 /********************
430 Edit multiple entries
431 ********************/
433 /* User wants to edit data? */
434 if ($s_action == "multiple_edit" && !isset($this->usertab->config)){
436 $this->dn = array();
437 foreach($this->list_get_selected_items() as $id){
438 $this->dn[] = $this->list[$id]['dn'];;
439 }
440 $tmp = new multi_plug($this->config,"usertabs",$this->config->data['TABS']['USERTABS'],
441 $this->dn,$this->DivListUsers->selectedBase,"user");
442 if ($tmp->entries_locked()){
443 return($tmp->display_lock_message());
444 }
445 $tmp->lock_entries($this->ui->dn);
446 if($tmp->multiple_available()){
447 $this->usertab = $tmp;
448 $this->usertab->set_active_tab($s_tab);
449 set_object_info($this->usertab->get_object_info());
450 }
451 }
454 /********************
455 Edit canceled
456 ********************/
458 /* Reset all relevant data, if we get a _cancel request */
459 if (isset($_POST['edit_cancel']) || isset($_POST['password_cancel'])){
460 if (isset($this->usertab)){
461 $this->remove_lock();
462 }
463 $this->usertab= NULL;
464 $this->lognames= array();;
465 $this->sn= "";
466 $this->givenName= "";
467 $this->uid= "";
468 set_object_info();
469 }
472 /********************
473 We want to create a new user, so fetch all available user templates
474 ********************/
476 /* Generate template list */
477 if ($s_action == "new" || $s_action == "create_user_from_tpl" || $s_action == "templatize_multiple"){
479 $this->templates= array();
480 $ldap= $this->config->get_ldap_link();
482 /* Create list of templates */
483 foreach ($this->config->departments as $key => $value){
485 /* Get acls from different ou's */
486 $acl = $this->ui->get_permissions($value,"users/user") ;
488 /* If creation of a new user is allowed, append this template */
489 if (preg_match("/c/",$acl)){
491 /* Search all templates from the current dn */
492 $ldap->cd (get_people_ou().$value);
493 $ldap->search ("(objectClass=gosaUserTemplate)", array("uid"));
495 /* Append */
496 if ($ldap->count() != 0){
497 while ($attrs= $ldap->fetch()){
498 $this->templates[$ldap->getDN()]=
499 $attrs['uid'][0]." - ".LDAP::fix($key);
500 }
501 if ($s_action != "templatize_multiple"){
502 $this->templates['none']= _("none");
503 }
504 }
505 }
506 }
508 /* Sort templates */
509 natcasesort ($this->templates);
510 reset ($this->templates);
511 }
514 /********************
515 Apply template to multiple entries requested, display confirm dialog
516 ********************/
518 if ($s_action=="templatize_multiple"){
519 $ids = $this->list_get_selected_items();
520 $this->dns = array();
521 if(count($ids)){
523 foreach($ids as $id){
524 $dn = $this->list[$id]['dn'];
525 if (($user= get_lock($dn)) != ""){
526 return(gen_locked_message ($user, $dn));
527 }
528 $this->dns[$id] = $dn;
529 }
530 }
532 $smarty->assign("templates", $this->templates);
534 return($smarty->fetch(get_template_path('templatize.tpl', TRUE)));
535 }
537 /* Perform templatizing after the button has been pressed */
538 if ($s_action == "templatize_continue"){
540 $acl = $this->ui->get_permissions($_POST['template'], "users/user");
542 /* Template readable? */
543 if (preg_match('/r/', $acl)){
544 $template_dn= $_POST['template'];
546 foreach ($this->dns as $dn){
547 $acl = $this->ui->get_permissions($_POST['template'], "users/user");
548 if (preg_match('/w/', $acl)){
549 $usertab= new usertabs($this->config, $this->config->data['TABS']['USERTABS'], $dn);
550 $usertab->adapt_from_template($template_dn, array("sn", "givenName", "uid"));
551 $usertab->save();
552 unset ($usertab);
553 $usertab= NULL;
554 } else {
555 msg_dialog::display(_("Permission error"), sprintf(_("You have no permission to modify object '%s'!"), $dn), ERROR_DIALOG);
556 }
557 }
558 } else {
559 msg_dialog::display(_("Permission error"), _("You have no permission to use this template!"), ERROR_DIALOG);
560 }
562 }
565 /********************
566 Delete MULTIPLE entries requested, display confirm dialog
567 ********************/
569 if ($s_action=="del_multiple" || $s_action == "del"){
571 if($s_action == "del"){
573 /* Get 'dn' from posted 'uid' */
574 $ids = array($s_entry);
575 }else{
576 $ids = $this->list_get_selected_items();
577 }
579 $this->dns = array();
580 if(count($ids)){
581 $disallowed = array();
582 foreach($ids as $id){
583 $dn = $this->list[$id]['dn'];
584 $acl = $this->ui->get_permissions($dn, "users/user");
585 if(preg_match("/d/",$acl)){
586 $this->dns[$id] = $dn;
587 }else{
588 $disallowed[] = $dn;
589 }
590 }
592 if(count($disallowed)){
593 msg_dialog::display(_("Permission"),msgPool::permDelete($disallowed),INFO_DIALOG);
594 }
596 if(count($this->dns)){
598 /* Check locks */
599 if ($user= get_multiple_locks($this->dns)){
600 return(gen_locked_message($user,$this->dns));
601 }
603 $dns_names = array();
604 foreach($this->dns as $dn){
605 $dns_names[] = LDAP::fix($dn);
606 }
608 add_lock($this->dns, $this->ui->dn);
610 /* Lock the current entry, so nobody will edit it during deletion */
611 $info = sprintf(msgPool::deleteInfo($dns_names,_("user")));
613 /* Lock the current entry, so nobody will edit it during deletion */
614 $smarty->assign("info", msgPool::deleteInfo($dns_names));
615 return($smarty->fetch(get_template_path('remove.tpl', TRUE)));
616 }
617 }
618 }
621 /********************
622 Delete MULTIPLE entries confirmed
623 ********************/
625 if(isset($_POST['delete_user_confirm'])){
627 /* Remove user by user and check acls before removeing them */
628 foreach($this->dns as $key => $dn){
630 $acl = $this->ui->get_permissions($dn, "users/user");
631 if (preg_match('/d/', $acl)){
633 /* Delete request is permitted, perform LDAP action */
634 $this->usertab= new usertabs($this->config, $this->config->data['TABS']['USERTABS'],$dn);
635 $this->usertab->set_acl_base();
636 $this->usertab->delete ();
637 unset ($this->usertab);
638 $this->usertab= NULL;
639 } else {
640 msg_dialog::display(_("Warning"),msgPool::permDelete($dn),WARNING_DIALOG);
641 if(isset($this->ui->uid)){
642 new log("security","users/".get_class($this),$dn,array(),"Tried to trick deletion.");
643 }
644 }
645 }
646 /* Remove lock file after successfull deletion */
647 $this->remove_lock();
648 $this->dns = array();
649 }
652 /********************
653 Toggle lock status for user
654 ********************/
656 if($s_action == "toggle_lock_status" && isset($this->list[$s_entry])){
658 /* Get entry check current status */
659 $val = $this->list[$s_entry];
660 if (!preg_match("/w/",$this->ui->get_permissions($val['dn'],"users/password"))){
661 msg_dialog::display(_("Account locking"),
662 _("You have no permission to change the lock status for this user!"),WARNING_DIALOG);
663 }else{
664 $pwd = $val['userPassword'][0];
665 $method = passwordMethod::get_method($pwd,$val['dn']);
666 $success= false;
667 if($method instanceOf passwordMethod){
668 if($method->is_locked($this->config,$val['dn'])){
669 $success= $method->unlock_account($this->config,$val['dn']);
670 }else{
671 $success= $method->lock_account($this->config,$val['dn']);
672 }
674 /* Check for success */
675 if (!$success){
676 $hn= $method->get_hash_name();
677 if (is_array($hn)){
678 $hn= $hn[0];
679 }
680 msg_dialog::display(_("Account locking"),
681 sprintf(_("Password method '%s' does not support locking. Account has not been locked!"), $hn),WARNING_DIALOG);
682 }
683 }else{
684 // Can't lock unknown methods.
685 }
687 }
688 }
690 /********************
691 Delete entry Canceled
692 ********************/
694 /* Delete user canceled? */
695 if (isset($_POST['delete_cancel'])){
697 /* Remove lock file after successfull deletion */
698 $this->remove_lock();
699 $this->dns = array();
700 }
703 /********************
704 Edit entry finished (Save)
705 ********************/
707 /* Finish user edit is triggered by the tabulator dialog, so
708 the user wants to save edited data. Check and save at this
709 point. */
710 if ((isset($_POST['edit_finish']) || isset($_POST['edit_apply'])) && (isset($this->usertab->config))){
712 /* Check tabs, will feed message array */
713 $this->usertab->last= $this->usertab->current;
714 $this->usertab->save_object();
715 $message= $this->usertab->check();
717 /* Save, or display error message? */
718 if (count($message) == 0){
720 /* No errors. Go ahead and prepare to ask for a password
721 in case we're creating a new user. 'dn' will be 'new'
722 in this case. It is set to the correct value later. */
723 if ($this->dn == "new"){
724 $set_pass= 1;
725 } else {
726 $set_pass= 0;
727 }
729 /* Save user data to ldap */
730 if($this->usertab->save() == 1){
731 return;
732 }
734 if (!isset($_POST['edit_apply'])){
735 /* User has been saved successfully, remove lock from LDAP. */
736 if ($this->dn != "new"){
737 $this->remove_lock();
738 }
740 /* In case of new users, ask for a password, skip this for templates */
741 if (($set_pass || $this->usertab->password_change_needed()) && !$this->is_template){
742 $this->dn = $this->usertab->dn;
743 return($smarty->fetch(get_template_path('password.tpl', TRUE)));
744 }
746 unset ($this->usertab);
747 $this->usertab= NULL;
748 set_object_info();
749 }else{
751 /* Reinitialize tab */
752 if($this->usertab instanceof tabs){
753 $this->usertab->re_init();
754 }
755 }
756 } else {
757 /* Ok. There seem to be errors regarding to the tab data,
758 show message and continue as usual. */
759 msg_dialog::displayChecks($message);
760 }
761 }
765 /********************
766 Create a new user,template, user from template
767 ********************/
769 /* Check selected options for template */
770 if (isset($_POST['template_continue'])){
771 $message = array();
772 if(!isset($_POST['template']) || (empty($_POST['template']))){
773 $message[]= msgPool::invalid(_("Template"));
774 }
775 if(!isset($_POST['sn']) || (empty($_POST['sn']))){
776 $message[]= msgPool::required(_("Name"));
777 }
778 if(!isset($_POST['givenName']) || (empty($_POST['givenName']))){
779 $message[]= msgPool::required(_("Given name"));
780 }
782 /* Show error message / continue editing */
783 if (count($message) > 0){
784 msg_dialog::displayChecks($message);
786 foreach(array("sn", "givenName", "uid", "template") as $attr){
787 if(isset($_POST[$attr])){
788 $smarty->assign("$attr", $_POST[$attr]);
789 }else{
790 $smarty->assign("$attr", "");
791 }
792 }
793 $smarty->assign("templates",$this->templates);
794 $smarty->assign("got_uid",$this->got_uid);
795 $smarty->assign("edit_uid",false);
796 return($smarty->fetch(get_template_path('template.tpl', TRUE)));
798 }
799 }
801 /* New user/template request */
802 if (($s_action=="create_user_from_tpl")||($s_action=="new") || ($s_action=="new_tpl")){
803 /* By default we set 'dn' to 'new', all relevant plugins will
804 react on this. */
805 $this->dn= "new";
807 $this->got_uid= ($this->config->get_cfg_value("idGenerator") == "");
809 /* Create new usertab object */
810 $this->usertab= new usertabs($this->config,$this->config->data['TABS']['USERTABS'], $this->dn);
811 $this->usertab->by_object['user']->base= $this->DivListUsers->selectedBase;
812 $this->usertab->set_acl_base($this->DivListUsers->selectedBase);
814 /* Take care about templates */
815 if ($s_action=="new_tpl"){
816 $this->is_template= TRUE;
817 $this->usertab->set_template_mode ();
818 } else {
819 $this->is_template= FALSE;
820 }
822 /* Use template if there are any of them */
823 if ((count($this->templates) && ($s_action!='new_tpl'))||($s_action=="create_user_from_tpl")){
824 foreach(array("sn", "givenName", "uid", "got_uid", "templates") as $attr){
825 $smarty->assign("$attr", $this->$attr);
826 }
827 if ($s_action=="create_user_from_tpl"){
828 $smarty->assign("template", $this->dn= $this->list[trim($s_entry)]['dn']);
829 } else {
830 $smarty->assign("template", "none");
831 }
832 $smarty->assign("edit_uid", "");
833 return($smarty->fetch(get_template_path('template.tpl', TRUE)));
834 }
835 }
837 /********************
838 Template selected continue edit
839 ********************/
841 /* Continue template editing */
842 if ((isset($_POST['template_continue'])) && ($_POST['template'] != 'none') && (!isset($_POST['uid']))){
844 $this->sn = $_POST['sn'];
845 $this->givenName = $_POST['givenName'];
847 /* Check for requred values */
848 $message= array();
849 if ($this->sn == "") {
850 $message[]= msgPool::required(_("Name"));
851 }
852 if ($this->givenName == "") {
853 $message[]= msgPool::required(_("Given name"));
854 }
856 /* Check if dn is used */
857 $dn= preg_replace("/^[^,]+,/i", "", $_POST['template']);
858 $ldap= $this->config->get_ldap_link();
859 $ldap->cd ($dn);
860 $ldap->search ("(&(sn=".normalizeLdap($this->sn).")(givenName=".normalizeLdap($this->givenName)."))", array("givenName"));
861 if ($ldap->count () != 0){
862 msgPool::duplicated(_("Name"));
863 }
865 /* Show error message / continue editing */
866 if (count($message) > 0){
867 msg_dialog::displayChecks($message);
868 } else {
869 $attributes= array('sn' => $this->sn, 'givenName' => $this->givenName);
870 if ($this->config->get_cfg_value("idGenerator") != ""){
871 $uids= gen_uids ($this->config->get_cfg_value("idGenerator"), $attributes);
872 if (count($uids)){
873 $smarty->assign("edit_uid", "false");
874 $smarty->assign("uids", $uids);
875 $this->uid= current($uids);
876 }
877 } else {
878 $smarty->assign("edit_uid", "");
879 $this->uid= "";
880 }
881 $this->got_uid= true;
882 }
884 foreach(array("sn", "givenName", "uid", "got_uid", "templates") as $attr){
885 $smarty->assign("$attr", $this->$attr);
886 }
887 if (isset($_POST['template'])){
888 $smarty->assign("template", $_POST['template']);
889 }
890 return($smarty->fetch(get_template_path('template.tpl', TRUE)));
891 }
893 /********************
894 No template selected continue edit
895 ********************/
897 /* No template. Ok. Lets fill data into the normal user dialog */
898 if (isset($_POST['template_continue']) && $_POST['template'] == 'none'){
899 foreach(array("sn", "givenName", "uid") as $attr){
900 if (isset($_POST[$attr])){
901 $this->usertab->by_object['user']->$attr= $_POST[$attr];
902 }
903 }
904 }
907 /********************
908 Template selected continue edit
909 ********************/
911 /* Finish template preamble */
912 if (isset($_POST['template_continue']) && $_POST['template'] != 'none' && (isset($_POST['uid']))){
914 /* Move user supplied data to sub plugins */
915 foreach(array("uid","sn","givenName") as $attr){
916 $this->$attr = $_POST[$attr];
917 $this->usertab->$attr = $this->$attr;
918 $this->usertab->by_object['user']->$attr = $this->$attr;
919 }
921 $template_dn = $_POST['template'];
922 $this->usertab->adapt_from_template($template_dn, array("uid","cn","givenName","sn"));
923 $template_base = preg_replace("/^[^,]+,".preg_quote(get_people_ou(), '/')."/", '', $template_dn);
924 $this->usertab->by_object['user']->base= $template_base;
925 }
928 /********************
929 If no template was selected set base
930 ********************/
932 if (isset($_POST['template_continue']) && ($_POST['template'] == 'none')){
933 $this->usertab->by_object['user']->base= $this->DivListUsers->selectedBase;
934 }
937 /********************
938 Display subdialog
939 ********************/
941 /* Show tab dialog if object is present */
942 if(isset($this->usertab->config)){
944 $display= $this->usertab->execute();
946 /* Don't show buttons if tab dialog requests this */
948 $dia = FALSE;
949 if(isset($this->usertab->by_object[$this->usertab->current]->dialog)){
950 $dia = $this->usertab->by_object[$this->usertab->current]->dialog;
951 }
953 if(!is_object($dia) && $dia != TRUE){
954 if(($this->usertab instanceOf tabs || $this->usertab instanceOf plugin) && $this->usertab->read_only == TRUE){
955 $display.= "<p style=\"text-align:right\">
956 <input type=submit name=\"edit_cancel\" value=\"".msgPool::cancelButton()."\">
957 </p>";
958 }else{
959 $display.= "<p style=\"text-align:right\">\n";
960 $display.= "<input type=submit name=\"edit_finish\" style=\"width:80px\" value=\"".msgPool::okButton()."\">\n";
961 $display.= " \n";
962 if ($this->dn != "new"){
963 $display.= "<input type=submit name=\"edit_apply\" value=\"".msgPool::applyButton()."\">\n";
964 $display.= " \n";
965 }
966 $display.= "<input type=submit name=\"edit_cancel\" value=\"".msgPool::cancelButton()."\">\n";
967 $display.= "</p>";
968 }
969 }
970 return ($display);
971 }
973 /* Check if there is a snapshot dialog open */
974 $base = $this->DivListUsers->selectedBase;
975 if($str = $this->showSnapshotDialog($base,$this->get_used_snapshot_bases(),$this)){
976 return($str);
977 }
979 /* Return rendered main page */
980 $this->DivListUsers->parent = $this;
981 $this->DivListUsers->execute();
983 /* Add departments if subsearch is disabled */
984 if(!$this->DivListUsers->SubSearch){
985 $this->DivListUsers->AddDepartments($this->DivListUsers->selectedBase,4,1);
986 }
987 $this->reload();
988 $this->DivListUsers->setEntries($this->list);
990 # FILTER Test #################################################
991 ## Build filter
992 #if (!$this->filter) {
993 # $this->filter = new filter(get_template_path("user-filter.xml", true));
994 # $this->filter->setObjectStorage(get_people_ou());
995 #}
996 #$this->filter->update();
997 #session::set('autocomplete', $this->filter);
998 #if (!$this->filter->isValid()){
999 # msg_dialog::display(_("Filter error"), _("The filter is uncomplete!"), ERROR_DIALOG);
1000 #}
1002 ## Build headpage
1003 #if (!$this->headpage){
1004 # $this->headpage = new listing(get_template_path("user-list.xml", true));
1005 # $this->headpage->registerElementFilter("accountProperties", "userManagement::filterProperties");
1006 # $this->headpage->registerElementFilter("lockLabel", "userManagement::filterLockLabel");
1007 # $this->headpage->registerElementFilter("lockImage", "userManagement::filterLockImage");
1008 # $this->headpage->setFilter($this->filter);
1009 #}
1011 ## Needs to be called before update!
1012 #$action= $this->headpage->getAction();
1013 #if ($action['action'] != '') {
1014 # echo "List detected action:";
1015 # print_a($action);
1016 #}
1018 ## Refresh for filter
1019 #$this->headpage->update();
1020 #
1021 #return($this->headpage->render());
1022 ################################################### FILTER Test
1024 return($this->DivListUsers->Draw());
1025 }
1028 static function filterLockImage($userPassword)
1029 {
1030 $image= "images/empty.png";
1032 if(isset($userPassword[0]) && preg_match("/^\{[^\}]/",$userPassword[0])){
1033 if(preg_match("/^[^\}]*+\}!/",$userPassword[0])){
1034 $image= "images/lists/locked.png";
1035 }else{
1036 $image= "images/lists/unlocked.png";
1037 }
1038 }
1040 return $image;
1041 }
1044 static function filterLockLabel($userPassword)
1045 {
1046 $label= "";
1048 if(isset($userPassword[0]) && preg_match("/^\{[^\}]/",$userPassword[0])){
1049 if(preg_match("/^[^\}]*+\}!/",$userPassword[0])){
1050 $label= _("Unlock account");
1051 }else{
1052 $label= _("Lock account");
1053 }
1054 }
1056 return $label;
1057 }
1060 static function filterProperties($dn, $row, $class)
1061 {
1062 $result= "";
1064 $map= array( "gosaAccount" => array( "image" => "plugins/users/images/select_user.png",
1065 "plugin" => "user",
1066 "alt" => _("Generic"),
1067 "title" => _("Edit generic properties")),
1068 "posixAccount" => array("image" => "images/penguin.png",
1069 "plugin" => "posixAccount",
1070 "alt" => _("POSIX"),
1071 "title" => _("Edit POSIX properties")),
1072 "gosaMailAccount" => array("image" => "images/mailto.png",
1073 "alt" => _("Mail"),
1074 "plugin" => "mailAccount",
1075 "title" => _("Edit mail properties")),
1076 "sambaSamAccount" => array("image" => "plugins/systems/images/select_winstation.png",
1077 "plugin" => "sambaAccount",
1078 "alt" => _("Samba"),
1079 "title" => _("Edit samba properties")),
1080 "apple-user" => array("image" => "plugins/netatalk/images/select_netatalk.png",
1081 "plugin" => "sambaAccount",
1082 "alt" => _("Netatalk"),
1083 "title" => _("Edit netatalk properties")),
1084 "gotoEnvironment" => array("image" => "plugins/users/images/small_environment.png",
1085 "plugin" => "gotoEnvironment",
1086 "alt" => _("Environment"),
1087 "title" => _("Edit environment properties")),
1088 "goFaxAccount" => array("image" => "plugins/users/images/fax_small.png",
1089 "plugin" => "goFaxAccount",
1090 "alt" => _("FAX"),
1091 "title" => _("Edit FAX properties")),
1092 "goFonAccount" => array("image" => "plugins/gofon/images/select_phone.png",
1093 "plugin" => "goFonAccount",
1094 "alt" => _("Phone"),
1095 "title" => _("Edit phone properties")));
1097 // Walk thru map
1098 foreach ($map as $oc => $properties) {
1099 if (in_array($oc, $class)) {
1100 $result.="<input class='center' type='image' src='".$properties['image']."' ".
1101 "alt='".$properties['alt']."' title='".$properties['title'].
1102 "' name='listing_edit_".$properties['plugin']."_$row' style='padding:1px'>";
1103 } else {
1104 $result.="<img src='images/empty.png' alt=' ' class='center' style='padding:1px'>";
1105 }
1106 }
1108 return $result;
1109 }
1113 /* Return departments, that will be included within snapshot detection */
1114 function get_used_snapshot_bases()
1115 {
1116 return(array(get_people_ou().$this->DivListUsers->selectedBase));
1117 }
1120 function reload()
1121 {
1122 /* Set base for all searches */
1123 $base= $this->DivListUsers->selectedBase;
1124 $this->list =array();
1126 /* Get filter configuration */
1127 $Regex = $this->DivListUsers->Regex;
1128 $SubSearch = $this->DivListUsers->SubSearch;
1129 $ShowTemplates = $this->DivListUsers->ShowTemplates;
1130 $ShowFunctionalUsers = $this->DivListUsers->ShowFunctionalUsers;
1131 $ShowUnixUsers = $this->DivListUsers->ShowUnixUsers;
1132 $ShowMailUsers = $this->DivListUsers->ShowMailUsers;
1133 $ShowSambaUsers = $this->DivListUsers->ShowSambaUsers;
1134 $ShowProxyUsers = $this->DivListUsers->ShowProxyUsers;
1136 /* Setup filter depending on selection */
1137 $filter="";
1138 $samba= "sambaSamAccount";
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 ?>