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 function userManagement(&$config, $ui)
47 {
48 /* Save configuration for internal use */
49 $this->config= &$config;
50 $this->ui= &$ui;
52 /* Copy & Paste handler */
53 if ($this->config->boolValueIsTrue("main", "copyPaste")){
54 $this->CopyPasteHandler= new CopyPasteHandler($this->config);
55 }
57 /* Creat dialog object */
58 $this->DivListUsers = new divListUsers($this->config,$this);
60 }
63 function execute()
64 {
65 /* Call parent execute */
66 plugin::execute();
68 /* LOCK MESSAGE Vars */
69 session::set('LOCK_VARS_TO_USE',array("/^act$/","/^id$/","/^user_edit_/","/^user_del_/","/^item_selected/","/^remove_multiple_users/","/^multiple_edit/","/menu_action/"));
71 $smarty = get_smarty(); // Smarty instance
72 $s_action = ""; // Contains the action to be taken
73 $s_entry = ""; // The value for s_action
75 /* Edit entry button pressed? */
76 if( isset($_GET['act']) && $_GET['act'] == "edit_entry" ){
77 $s_action= "edit";
78 $s_entry= validate($_GET['id']);
79 }
81 /* Test relevant POST values */
82 foreach($_POST as $key => $val){
84 /* Get every possible POST combination and set s_action/s_entry accordingly */
85 foreach(array("del" => "user_del",
86 "edit" => "user_edit",
87 "new" => "user_new",
88 "new_tpl" => "user_tplnew",
89 "del_multiple" => "^remove_multiple_users",
90 "create_user_from_tpl" => "userfrom_tpl",
91 "change_pw" => "user_chgpw",
92 "editPaste" => "editPaste",
93 "copy_multiple" => "multiple_copy_users",
94 "multiple_edit" => "multiple_edit",
95 "cut_multiple" => "multiple_cut_users",
96 "multiple_password_change" => "multiple_password_change",
97 "copy" => "^copy",
98 "toggle_lock_status" => "toggle_lock_status",
99 "cut" => "^cut") as $act => $name){
101 if (preg_match("/".$name.".*/", $key)){
102 $s_action= $act;
103 $s_entry= preg_replace("/".$name."_/i", "", $key);
104 break;
105 }
106 }
108 } /* ...Test POST */
110 /* Remove coordinate prefix from POST, required by some browsers */
111 $s_entry= preg_replace("/_.$/", "", $s_entry);
113 /* Seperate possibly encoded tab and entry, default to tab "user" */
114 if(preg_match("/.*-.*/", $s_entry)){
115 $s_tab= preg_replace("/^[^-]*-/i", "" ,$s_entry);
116 $s_entry= preg_replace("/-[^-]*$/i", "", $s_entry);
117 }else{
118 $s_tab= "user";
119 }
121 if(!$this->config->search($s_tab, 'class',array('tabs'))){
122 $s_tab = "user";
123 }
125 if (isset($_POST['menu_action'])){
127 /* handle C&P from layers menu */
128 if(preg_match("/^multiple_copy_systems/",$_POST['menu_action'])){
129 $s_action = "copy_multiple";
130 }
131 if(preg_match("/^multiple_cut_systems/",$_POST['menu_action'])){
132 $s_action = "cut_multiple";
133 }
134 if(preg_match("/^editPaste/",$_POST['menu_action'])){
135 $s_action = "editPaste";
136 }
138 /* Create options */
139 if($_POST['menu_action'] == "user_new"){
140 $s_action = "new";
141 }
142 if($_POST['menu_action'] == "user_tplnew"){
143 $s_action = "new_tpl";
144 }
145 if($_POST['menu_action'] == "multiple_edit"){
146 $s_action = "multiple_edit";
147 }
149 /* handle remove from layers menu */
150 if(preg_match("/^multiple_password_change/",$_POST['menu_action'])){
151 $s_action = "multiple_password_change";
152 }
154 /* handle remove from layers menu */
155 if(preg_match("/^remove_multiple/",$_POST['menu_action'])){
156 $s_action = "del_multiple";
157 }
158 if(preg_match("/^templatize_multiple/",$_POST['menu_action'])){
159 $s_action = "templatize_multiple";
160 }
162 if(preg_match("/^event/",$_POST['menu_action'])){
163 $s_action = $_POST['menu_action'];
164 }
165 }
167 /* Use template */
168 if(isset($_POST['templatize_continue'])){
169 $s_action = "templatize_continue";
170 }
173 /********************
174 Create notification event
175 ********************/
177 if(preg_match("/^event_/",$s_action) && class_available("DaemonEvent")){
178 $ids = $this->list_get_selected_items();
179 $uids = array();
180 foreach($ids as $id){
181 $uids[] = $this->list[$id]['uid'][0];
182 }
183 if(count($uids)){
184 $events = DaemonEvent::get_event_types(USER_EVENT);
185 $event = preg_replace("/^event_/","",$s_action);
186 if(isset($events['BY_CLASS'][$event])){
187 $type = $events['BY_CLASS'][$event];
188 $this->usertab = new $type['CLASS_NAME']($this->config);
189 $this->usertab->add_users($uids);
190 $this->usertab->set_type(TRIGGERED_EVENT);
191 }
192 }
193 }
195 /* Abort event dialog */
196 if(isset($_POST['abort_event_dialog'])){
197 $this->usertab = FALSE;
198 }
200 /* Save event */
201 if(isset($_POST['save_event_dialog'])){
202 $this->usertab->save_object();
203 $msgs = $this->usertab->check();
204 if(count($msgs)){
205 msg_dialog::displayChecks($msgs);
206 }else{
208 $o_queue = new gosaSupportDaemon();
209 $o_queue->append($this->usertab);
210 if($o_queue->is_error()){
211 msg_dialog::display(_("Infrastructure error"), msgPool::siError($o_queue->get_error()),ERROR_DIALOG);
212 }else{
213 $this->usertab = FALSE;
214 }
215 }
216 }
218 /* Display event */
219 if($this->usertab instanceof DaemonEvent){
220 $this->usertab->save_object();
221 return($this->usertab->execute());
222 }
225 /********************
226 Copy & Paste
227 ********************/
229 /* Display the copy & paste dialog, if it is currently open */
230 if($this->CPPasswordChange == ""){
231 $ret = $this->copyPasteHandling_from_queue($s_action,$s_entry);
232 if($ret){
233 return($ret);
234 }
235 }
238 /********************
239 Change password confirmed
240 ********************/
242 /* Perform password change */
243 if (isset($_POST['password_finish'])){
245 /* For security reasons, check if user is allowed to set password again */
246 $dn = $this->dn;
247 $acl = $this->ui->get_permissions($dn, "users/password");
248 $cacl= $this->ui->get_permissions($dn, "users/user");
250 /* Are we allowed to create a new user or to set the password attribute? */
251 if (preg_match('/w/', $acl) || preg_match('/c/', $cacl)){
253 /* Check input and feed errors into 'message' */
254 $message= array();
256 /* Sanity checks... */
257 if ($_POST['new_password'] != $_POST['repeated_password']){
259 /* Matching passwords in new and repeated? */
260 $message[]= _("The passwords you've entered as 'New password' and 'Repeated new password' do not match.");
261 } else {
263 /* Empty password is not permitted by default. */
264 if ($_POST['new_password'] == ""){
265 msgPool::required(_("New password"));
266 }
267 }
269 /* Errors, or password change? */
270 if (count($message) != 0){
272 /* Show error message and continue editing */
273 msg_dialog::displayChecks($message);
274 return($smarty->fetch(get_template_path('password.tpl', TRUE)));
275 }
277 $config= $this->config;
278 $ldap_ui= $this->config->get_ldap_link();
279 if(isset($this->usertab->dn)){
280 $ldap_ui->cat($this->usertab->dn,array("uid"));
281 $user = $ldap_ui->fetch();
282 }else{
283 $ldap_ui->cat($this->dn,array("uid"));
284 $user = $ldap_ui->fetch();
285 }
286 if((is_array($user))&&(isset($user['uid']))){
287 $username= $user['uid'][0];
288 }
290 /* Set password, perform required steps */
291 if ($this->usertab){
292 if ($this->usertab->password_change_needed()){
293 $obj= $this->usertab->by_object['user'];
294 if(!change_password ($this->usertab->dn, $_POST['new_password'],0, $obj->pw_storage)){
295 return($smarty->fetch(get_template_path('password.tpl', TRUE)));
296 }
297 if ($config->get_cfg_value("passwordHook") != ""){
298 exec($config->get_cfg_value("passwordHook")." ".$username." ".$_POST['new_password'], $resarr);
299 }
300 new log("modify","users/".get_class($this),$this->usertab->dn,array(),"Password has been changed");
301 unset($this->usertab);
302 $this->usertab= NULL;
303 }
304 } else {
305 if(!change_password ($this->dn, $_POST['new_password'])){
306 return($smarty->fetch(get_template_path('password.tpl', TRUE)));
307 }
308 if ($config->get_cfg_value("passwordHook") != ""){
309 exec($config->get_cfg_value("passwordHook")." ".$username." ".$_POST['new_password'], $resarr);
310 }
311 new log("modify","users/".get_class($this),$this->dn,array(),"Password has been changed");
312 }
313 } else {
315 /* Missing permissions, show message */
316 msg_dialog::display(_("Password change"),_("You have no permission to change this users password!"),WARNING_DIALOG);
317 }
318 /* Clean session, delete lock */
319 $this->remove_lock();
320 unset ($this->usertab);
321 $this->usertab= NULL;
322 $this->lognames= array();;
323 $this->sn= "";
324 $this->givenName= "";
325 $this->uid= "";
326 session::un_set('objectinfo');
327 }
330 /********************
331 Change multiple passwords requested
332 ********************/
334 if($s_action == "multiple_password_change"){
335 $this->pwd_change_queue = $this->list_get_selected_items();
336 $disallowed = array();
337 foreach($this->pwd_change_queue as $key => $id){
338 if(!preg_match("/w/",$this->ui->get_permissions($this->list[trim($id)]['dn'],"users/password"))){
339 unset($this->pwd_change_queue[$key]);
340 $disallowed[] = $this->list[trim($id)]['dn'];
341 }
342 }
343 if(count($disallowed)){
344 msg_dialog::display(_("Permission"),msgPool::permModify($disallowed),INFO_DIALOG);
345 }
346 }
349 /********************
350 Change password requested
351 ********************/
353 /* Password change requested */
354 if (($s_action == "change_pw") || (!empty($this->CPPasswordChange)) || count($this->pwd_change_queue)){
356 /* Get users whose passwords should be changed. */
357 if(count($this->pwd_change_queue)){
358 $s_entry= array_pop($this->pwd_change_queue);
359 }
361 if(!empty($this->CPPasswordChange)){
362 $s_entry = $this->CPPasswordChange;
363 $this->CPPasswordChange = "";
364 }
366 /* Get 'dn' from posted 'uid' */
367 $this->dn= $this->list[trim($s_entry)]['dn'];
369 /* Load permissions for selected 'dn' and check if
370 we're allowed to remove this 'dn' */
371 if (preg_match("/w/",$this->ui->get_permissions($this->dn,"users/password"))){
373 /* User is allowed to change passwords, save 'dn' and 'acl' for next
374 dialog. */
375 session::set('objectinfo',$this->dn);
376 return ($smarty->fetch(get_template_path('password.tpl', TRUE)));
377 } else {
378 /* User is not allowed. Show message and cancel. */
379 msg_dialog::display(_("Password change"),_("You have no permission to change this users password!"),WARNING_DIALOG);
380 }
381 }
385 /********************
386 Edit existing entry
387 ********************/
390 /* User wants to edit data? */
391 if (($s_action=="edit") && (!isset($this->usertab->config))){
393 /* Get 'dn' from posted 'uid', must be unique */
394 $this->dn= $this->list[trim($s_entry)]['dn'];
396 /* Check locking, save current plugin in 'back_plugin', so
397 the dialog knows where to return. */
398 if (($user= get_lock($this->dn)) != ""){
399 return(gen_locked_message ($user, $this->dn,TRUE));
400 }
402 /* Lock the current entry, so everyone will get the
403 above dialog */
404 add_lock ($this->dn, $this->ui->dn);
406 /* Register usertab to trigger edit dialog */
407 $this->usertab= new usertabs($this->config,
408 $this->config->data['TABS']['USERTABS'], $this->dn);
410 /* Switch tab, if it was requested by the user */
411 $this->usertab->current = $s_tab;
413 /* Set ACL and move DN to the headline */
414 $this->usertab->set_acl_base($this->dn);
415 session::set('objectinfo',$this->dn);
416 }
419 /********************
420 Edit multiple entries
421 ********************/
423 /* User wants to edit data? */
424 if ($s_action == "multiple_edit" && !isset($this->usertab->config)){
426 $this->dn = array();
427 foreach($this->list_get_selected_items() as $id){
428 $this->dn[] = $this->list[$id]['dn'];;
429 }
430 $tmp = new multi_plug($this->config,"usertabs",$this->config->data['TABS']['USERTABS'],
431 $this->dn,$this->DivListUsers->selectedBase,"user");
432 if ($tmp->entries_locked()){
433 return($tmp->display_lock_message());
434 }
435 $tmp->lock_entries($this->ui->dn);
436 if($tmp->multiple_available()){
437 $this->usertab = $tmp;
438 $this->usertab->set_active_tab($s_tab);
439 session::set('objectinfo',$this->usertab->get_object_info());
440 }
441 }
444 /********************
445 Edit canceled
446 ********************/
448 /* Reset all relevant data, if we get a _cancel request */
449 if (isset($_POST['edit_cancel']) || isset($_POST['password_cancel'])){
450 if (isset($this->usertab)){
451 $this->remove_lock();
452 }
453 $this->usertab= NULL;
454 $this->lognames= array();;
455 $this->sn= "";
456 $this->givenName= "";
457 $this->uid= "";
458 session::un_set('objectinfo');
459 }
462 /********************
463 We want to create a new user, so fetch all available user templates
464 ********************/
466 /* Generate template list */
467 if ($s_action == "new" || $s_action == "create_user_from_tpl" || $s_action == "templatize_multiple"){
469 $this->templates= array();
470 $ldap= $this->config->get_ldap_link();
472 /* Create list of templates */
473 foreach ($this->config->departments as $key => $value){
475 /* Get acls from different ou's */
476 $acl = $this->ui->get_permissions($value,"users/user") ;
478 /* If creation of a new user is allowed, append this template */
479 if (preg_match("/c/",$acl)){
481 /* Search all templates from the current dn */
482 $ldap->cd (get_people_ou().$value);
483 $ldap->search ("(objectClass=gosaUserTemplate)", array("uid"));
485 /* Append */
486 if ($ldap->count() != 0){
487 while ($attrs= $ldap->fetch()){
488 $this->templates[$ldap->getDN()]=
489 $attrs['uid'][0]." - ".LDAP::fix($key);
490 }
491 if ($s_action != "templatize_multiple"){
492 $this->templates['none']= _("none");
493 }
494 }
495 }
496 }
498 /* Sort templates */
499 natcasesort ($this->templates);
500 reset ($this->templates);
501 }
504 /********************
505 Apply template to multiple entries requested, display confirm dialog
506 ********************/
508 if ($s_action=="templatize_multiple"){
509 $ids = $this->list_get_selected_items();
510 $this->dns = array();
511 if(count($ids)){
513 foreach($ids as $id){
514 $dn = $this->list[$id]['dn'];
515 if (($user= get_lock($dn)) != ""){
516 return(gen_locked_message ($user, $dn));
517 }
518 $this->dns[$id] = $dn;
519 }
520 }
522 $smarty->assign("templates", $this->templates);
524 return($smarty->fetch(get_template_path('templatize.tpl', TRUE)));
525 }
527 /* Perform templatizing after the button has been pressed */
528 if ($s_action == "templatize_continue"){
530 $acl = $this->ui->get_permissions($_POST['template'], "users/user");
532 /* Template readable? */
533 if (preg_match('/r/', $acl)){
534 $template_dn= $_POST['template'];
536 foreach ($this->dns as $dn){
537 $acl = $this->ui->get_permissions($_POST['template'], "users/user");
538 if (preg_match('/w/', $acl)){
539 $usertab= new usertabs($this->config, $this->config->data['TABS']['USERTABS'], $dn);
540 $usertab->adapt_from_template($template_dn, array("sn", "givenName", "uid"));
541 $usertab->save();
542 unset ($usertab);
543 $usertab= NULL;
544 } else {
545 msg_dialog::display(_("Permission error"), sprintf(_("You have no permission to modify object '%s'!"), $dn), ERROR_DIALOG);
546 }
547 }
548 } else {
549 msg_dialog::display(_("Permission error"), _("You have no permission to use this template!"), ERROR_DIALOG);
550 }
552 }
555 /********************
556 Delete MULTIPLE entries requested, display confirm dialog
557 ********************/
559 if ($s_action=="del_multiple" || $s_action == "del"){
561 if($s_action == "del"){
563 /* Get 'dn' from posted 'uid' */
564 $ids = array($s_entry);
565 }else{
566 $ids = $this->list_get_selected_items();
567 }
569 $this->dns = array();
570 if(count($ids)){
571 $disallowed = array();
572 foreach($ids as $id){
573 $dn = $this->list[$id]['dn'];
574 $acl = $this->ui->get_permissions($dn, "users/user");
575 if(preg_match("/d/",$acl)){
576 $this->dns[$id] = $dn;
577 }else{
578 $disallowed[] = $dn;
579 }
580 }
582 if(count($disallowed)){
583 msg_dialog::display(_("Permission"),msgPool::permDelete($disallowed),INFO_DIALOG);
584 }
586 if(count($this->dns)){
588 /* Check locks */
589 if ($user= get_multiple_locks($this->dns)){
590 return(gen_locked_message($user,$this->dns));
591 }
593 $dns_names = array();
594 foreach($this->dns as $dn){
595 $dns_names[] = LDAP::fix($dn);
596 }
598 add_lock($this->dns, $this->ui->dn);
600 /* Lock the current entry, so nobody will edit it during deletion */
601 $info = sprintf(msgPool::deleteInfo($dns_names,_("user")));
603 /* Lock the current entry, so nobody will edit it during deletion */
604 $smarty->assign("info", msgPool::deleteInfo($dns_names));
605 return($smarty->fetch(get_template_path('remove.tpl', TRUE)));
606 }
607 }
608 }
611 /********************
612 Delete MULTIPLE entries confirmed
613 ********************/
615 if(isset($_POST['delete_user_confirm'])){
617 /* Remove user by user and check acls before removeing them */
618 foreach($this->dns as $key => $dn){
620 $acl = $this->ui->get_permissions($dn, "users/user");
621 if (preg_match('/d/', $acl)){
623 /* Delete request is permitted, perform LDAP action */
624 $this->usertab= new usertabs($this->config, $this->config->data['TABS']['USERTABS'],$dn);
625 $this->usertab->set_acl_base();
626 $this->usertab->delete ();
627 unset ($this->usertab);
628 $this->usertab= NULL;
629 } else {
630 msg_dialog::display(_("Warning"),msgPool::permDelete($dn),WARNING_DIALOG);
631 if(isset($this->ui->uid)){
632 new log("security","users/".get_class($this),$dn,array(),"Tried to trick deletion.");
633 }
634 }
635 }
636 /* Remove lock file after successfull deletion */
637 $this->remove_lock();
638 $this->dns = array();
639 }
642 /********************
643 Toggle lock status for user
644 ********************/
646 if($s_action == "toggle_lock_status" && isset($this->list[$s_entry])){
648 /* Get entry check current status */
649 $val = $this->list[$s_entry];
650 if (!preg_match("/w/",$this->ui->get_permissions($val['dn'],"users/password"))){
651 msg_dialog::display(_("Password change"),
652 _("You have no permission to change the lock status for this user!"),WARNING_DIALOG);
653 }else{
654 $pwd = $val['userPassword'][0];
655 $method = passwordMethod::get_method($pwd,$val['dn']);
656 if($method instanceOf passwordMethod){
657 if($method->is_locked($this->config,$val['dn'])){
658 $method->unlock_account($this->config,$val['dn']);
659 }else{
660 $method->lock_account($this->config,$val['dn']);
661 }
662 }else{
663 // Can't lock unknown methods.
664 }
665 }
666 }
668 /********************
669 Delete entry Canceled
670 ********************/
672 /* Delete user canceled? */
673 if (isset($_POST['delete_cancel'])){
675 /* Remove lock file after successfull deletion */
676 $this->remove_lock();
677 $this->dns = array();
678 }
681 /********************
682 Edit entry finished (Save)
683 ********************/
685 /* Finish user edit is triggered by the tabulator dialog, so
686 the user wants to save edited data. Check and save at this
687 point. */
688 if ((isset($_POST['edit_finish']) || isset($_POST['edit_apply'])) && (isset($this->usertab->config))){
690 /* Check tabs, will feed message array */
691 $this->usertab->last= $this->usertab->current;
692 $this->usertab->save_object();
693 $message= $this->usertab->check();
695 /* Save, or display error message? */
696 if (count($message) == 0){
698 /* No errors. Go ahead and prepare to ask for a password
699 in case we're creating a new user. 'dn' will be 'new'
700 in this case. It is set to the correct value later. */
701 if ($this->dn == "new"){
702 $set_pass= 1;
703 } else {
704 $set_pass= 0;
705 }
707 /* Save user data to ldap */
708 if($this->usertab->save() == 1){
709 return;
710 }
712 if (!isset($_POST['edit_apply'])){
713 /* User has been saved successfully, remove lock from LDAP. */
714 if ($this->dn != "new"){
715 $this->remove_lock();
716 }
718 /* In case of new users, ask for a password, skip this for templates */
719 if (($set_pass || $this->usertab->password_change_needed()) && !$this->is_template){
720 $this->dn = $this->usertab->dn;
721 return($smarty->fetch(get_template_path('password.tpl', TRUE)));
722 }
724 unset ($this->usertab);
725 $this->usertab= NULL;
726 session::un_set('objectinfo');
727 }else{
729 /* Reinitialize tab */
730 if($this->usertab instanceof tabs){
731 $this->usertab->re_init();
732 }
733 }
734 } else {
735 /* Ok. There seem to be errors regarding to the tab data,
736 show message and continue as usual. */
737 msg_dialog::displayChecks($message);
738 }
739 }
743 /********************
744 Create a new user,template, user from template
745 ********************/
747 /* Check selected options for template */
748 if (isset($_POST['template_continue'])){
749 $message = array();
750 if(!isset($_POST['template']) || (empty($_POST['template']))){
751 $message[]= msgPool::invalid(_("Template"));
752 }
753 if(!isset($_POST['sn']) || (empty($_POST['sn']))){
754 $message[]= msgPool::required(_("Name"));
755 }
756 if(!isset($_POST['givenName']) || (empty($_POST['givenName']))){
757 $message[]= msgPool::required(_("Given name"));
758 }
760 /* Show error message / continue editing */
761 if (count($message) > 0){
762 msg_dialog::displayChecks($message);
764 foreach(array("sn", "givenName", "uid", "template") as $attr){
765 if(isset($_POST[$attr])){
766 $smarty->assign("$attr", $_POST[$attr]);
767 }else{
768 $smarty->assign("$attr", "");
769 }
770 }
771 $smarty->assign("templates",$this->templates);
772 $smarty->assign("got_uid",$this->got_uid);
773 $smarty->assign("edit_uid",false);
774 return($smarty->fetch(get_template_path('template.tpl', TRUE)));
776 }
777 }
779 /* New user/template request */
780 if (($s_action=="create_user_from_tpl")||($s_action=="new") || ($s_action=="new_tpl")){
781 /* By default we set 'dn' to 'new', all relevant plugins will
782 react on this. */
783 $this->dn= "new";
785 $this->got_uid= ($this->config->get_cfg_value("idGenerator") == "");
787 /* Create new usertab object */
788 $this->usertab= new usertabs($this->config,$this->config->data['TABS']['USERTABS'], $this->dn);
789 $this->usertab->by_object['user']->base= $this->DivListUsers->selectedBase;
790 $this->usertab->set_acl_base($this->DivListUsers->selectedBase);
792 /* Take care about templates */
793 if ($s_action=="new_tpl"){
794 $this->is_template= TRUE;
795 $this->usertab->set_template_mode ();
796 } else {
797 $this->is_template= FALSE;
798 }
800 /* Use template if there are any of them */
801 if ((count($this->templates) && ($s_action!='new_tpl'))||($s_action=="create_user_from_tpl")){
802 foreach(array("sn", "givenName", "uid", "got_uid", "templates") as $attr){
803 $smarty->assign("$attr", $this->$attr);
804 }
805 if ($s_action=="create_user_from_tpl"){
806 $smarty->assign("template", $this->dn= $this->list[trim($s_entry)]['dn']);
807 } else {
808 $smarty->assign("template", "none");
809 }
810 $smarty->assign("edit_uid", "");
811 return($smarty->fetch(get_template_path('template.tpl', TRUE)));
812 }
813 }
815 /********************
816 Template selected continue edit
817 ********************/
819 /* Continue template editing */
820 if ((isset($_POST['template_continue'])) && ($_POST['template'] != 'none') && (!isset($_POST['uid']))){
822 $this->sn = $_POST['sn'];
823 $this->givenName = $_POST['givenName'];
825 /* Check for requred values */
826 $message= array();
827 if ($this->sn == "") {
828 $message[]= msgPool::required(_("Name"));
829 }
830 if ($this->givenName == "") {
831 $message[]= msgPool::required(_("Given name"));
832 }
834 /* Check if dn is used */
835 $dn= preg_replace("/^[^,]+,/i", "", $_POST['template']);
836 $ldap= $this->config->get_ldap_link();
837 $ldap->cd ($dn);
838 $ldap->search ("(&(sn=".normalizeLdap($this->sn).")(givenName=".normalizeLdap($this->givenName)."))", array("givenName"));
839 if ($ldap->count () != 0){
840 msgPool::duplicated(_("Name"));
841 }
843 /* Show error message / continue editing */
844 if (count($message) > 0){
845 msg_dialog::displayChecks($message);
846 } else {
847 $attributes= array('sn' => $this->sn, 'givenName' => $this->givenName);
848 if ($this->config->get_cfg_value("idGenerator") != ""){
849 $uids= gen_uids ($this->config->get_cfg_value("idGenerator"), $attributes);
850 if (count($uids)){
851 $smarty->assign("edit_uid", "false");
852 $smarty->assign("uids", $uids);
853 $this->uid= current($uids);
854 }
855 } else {
856 $smarty->assign("edit_uid", "");
857 $this->uid= "";
858 }
859 $this->got_uid= true;
860 }
862 foreach(array("sn", "givenName", "uid", "got_uid", "templates") as $attr){
863 $smarty->assign("$attr", $this->$attr);
864 }
865 if (isset($_POST['template'])){
866 $smarty->assign("template", $_POST['template']);
867 }
868 return($smarty->fetch(get_template_path('template.tpl', TRUE)));
869 }
871 /********************
872 No template selected continue edit
873 ********************/
875 /* No template. Ok. Lets fill data into the normal user dialog */
876 if (isset($_POST['template_continue']) && $_POST['template'] == 'none'){
877 foreach(array("sn", "givenName", "uid") as $attr){
878 if (isset($_POST[$attr])){
879 $this->usertab->by_object['user']->$attr= $_POST[$attr];
880 }
881 }
882 }
885 /********************
886 Template selected continue edit
887 ********************/
889 /* Finish template preamble */
890 if (isset($_POST['template_continue']) && $_POST['template'] != 'none' && (isset($_POST['uid']))){
892 /* Might not be filled if IDGEN is unset */
893 $this->sn = $_POST['sn'];
894 $this->givenName = $_POST['givenName'];
896 /* Move user supplied data to sub plugins */
897 $this->uid = $_POST['uid'];
898 $this->usertab->uid = $this->uid;
899 $this->usertab->sn = $this->sn;
900 $this->usertab->givenName = $this->givenName;
901 $template_dn = $_POST['template'];
902 $this->usertab->adapt_from_template($template_dn);
903 $template_base = preg_replace("/^[^,]+,".preg_quote(get_people_ou(), '/')."/", '', $template_dn);
904 $this->usertab->by_object['user']->base= $template_base;
905 }
908 /********************
909 If no template was selected set base
910 ********************/
912 if (isset($_POST['template_continue']) && ($_POST['template'] == 'none')){
913 $this->usertab->by_object['user']->base= $this->DivListUsers->selectedBase;
914 }
917 /********************
918 Display subdialog
919 ********************/
921 /* Show tab dialog if object is present */
922 if(isset($this->usertab->config)){
924 $display= $this->usertab->execute();
926 /* Don't show buttons if tab dialog requests this */
928 $dia = FALSE;
929 if(isset($this->usertab->by_object[$this->usertab->current]->dialog)){
930 $dia = $this->usertab->by_object[$this->usertab->current]->dialog;
931 }
933 if(!is_object($dia) && $dia != TRUE){
934 if(($this->usertab instanceOf tabs || $this->usertab instanceOf plugin) && $this->usertab->read_only == TRUE){
935 $display.= "<p style=\"text-align:right\">
936 <input type=submit name=\"edit_cancel\" value=\"".msgPool::cancelButton()."\">
937 </p>";
938 }else{
939 $display.= "<p style=\"text-align:right\">\n";
940 $display.= "<input type=submit name=\"edit_finish\" style=\"width:80px\" value=\"".msgPool::okButton()."\">\n";
941 $display.= " \n";
942 if ($this->dn != "new"){
943 $display.= "<input type=submit name=\"edit_apply\" value=\"".msgPool::applyButton()."\">\n";
944 $display.= " \n";
945 }
946 $display.= "<input type=submit name=\"edit_cancel\" value=\"".msgPool::cancelButton()."\">\n";
947 $display.= "</p>";
948 }
949 }
950 return ($display);
951 }
953 /* Check if there is a snapshot dialog open */
954 $base = $this->DivListUsers->selectedBase;
955 if($str = $this->showSnapshotDialog($base,$this->get_used_snapshot_bases(),$this)){
956 return($str);
957 }
959 /* Return rendered main page */
960 /* Display dialog with system list */
961 $this->DivListUsers->parent = $this;
962 $this->DivListUsers->execute();
964 /* Add departments if subsearch is disabled */
965 if(!$this->DivListUsers->SubSearch){
966 $this->DivListUsers->AddDepartments($this->DivListUsers->selectedBase,4,1);
967 }
968 $this->reload();
969 $this->DivListUsers->setEntries($this->list);
970 return($this->DivListUsers->Draw());
971 }
974 /* Return departments, that will be included within snapshot detection */
975 function get_used_snapshot_bases()
976 {
977 return(array(get_people_ou().$this->DivListUsers->selectedBase));
978 }
981 function reload()
982 {
983 /* Set base for all searches */
984 $base= $this->DivListUsers->selectedBase;
985 $this->list =array();
987 /* Get filter configuration */
988 $Regex = $this->DivListUsers->Regex;
989 $SubSearch = $this->DivListUsers->SubSearch;
990 $ShowTemplates = $this->DivListUsers->ShowTemplates;
991 $ShowFunctionalUsers = $this->DivListUsers->ShowFunctionalUsers;
992 $ShowUnixUsers = $this->DivListUsers->ShowUnixUsers;
993 $ShowMailUsers = $this->DivListUsers->ShowMailUsers;
994 $ShowSambaUsers = $this->DivListUsers->ShowSambaUsers;
995 $ShowProxyUsers = $this->DivListUsers->ShowProxyUsers;
997 /* Setup filter depending on selection */
998 $filter="";
999 if ($this->config->get_cfg_value("sambaversion") == 3){
1000 $samba= "sambaSamAccount";
1001 } else {
1002 $samba= "sambaAccount";
1003 }
1005 if ($ShowFunctionalUsers){
1006 $filter.= "(&(objectClass=gosaAccount)(!(|(objectClass=posixAccount)".
1007 "(objectClass=gosaMailAccount)(objectClass=$samba)".
1008 "(objectClass=gosaProxyAccount))))";
1009 }
1010 if ($ShowUnixUsers){
1011 $filter.= "(objectClass=posixAccount)";
1012 }
1013 if ($ShowMailUsers){
1014 $filter.= "(objectClass=gosaMailAccount)";
1015 }
1016 if ($ShowSambaUsers){
1017 $filter.= "(objectClass=$samba)";
1018 }
1019 if ($ShowProxyUsers){
1020 $filter.= "(objectClass=gosaProxyAccount)";
1021 }
1022 if ($ShowTemplates){
1023 $filter= "(|(objectClass=gosaUserTemplate)(&(objectClass=gosaAccount)(|$filter)))";
1024 } else {
1025 $filter= "(&(objectClass=gosaAccount)(objectClass=person)".
1026 "(objectClass=inetOrgPerson)(objectClass=organizationalPerson)".
1027 "(!(objectClass=gosaUserTemplate))(|$filter))";
1028 }
1029 $filter= "(&(|(uid=".normalizeLdap($Regex).")(sn=".normalizeLdap($Regex).")(givenName=".normalizeLdap($Regex)."))$filter)";
1031 /* Generate userlist */
1032 $ldap= $this->config->get_ldap_link(TRUE);
1034 if ($SubSearch){
1035 $ListTemp = get_sub_list($filter, "users", get_people_ou(),$base,
1036 array("uid", "givenName", "sn", "objectClass","userPassword"), GL_SUBSEARCH | GL_SIZELIMIT);
1037 } else {
1038 $base= get_people_ou().$base;
1039 $ListTemp = get_sub_list($filter, "users", get_people_ou(),$base,
1040 array("uid", "givenName", "sn", "objectClass","userPassword"), GL_SIZELIMIT);
1041 }
1042 $SortTemp = array();
1043 $List = array();
1045 foreach($ListTemp as $Key => $Entry){
1047 /* Due to the fact that "inetOrgPerson" is derived from "organizationalPerson" and that openldap
1048 doesn't differentiate both classes in search filters, we have to skip entries that do not provide
1049 both classes. (Both classes are required for a valid GOsa user Account.)
1050 */
1051 if(!in_array("inetOrgPerson",$Entry['objectClass'])|| !in_array("organizationalPerson",$Entry['objectClass'])){
1052 continue;
1053 }
1055 /* Skip entries that are not located under the people ou (normaly 'ou=people,')
1056 * Else winstations will be listed too, if you use the subtree flag.
1057 */
1058 if(!preg_match("/".preg_quote(get_people_ou(), '/')."/i",$Entry['dn'])){
1059 continue;
1060 }else{
1062 // Generate caption for rows
1063 if (isset($Entry["sn"]) && isset($Entry["givenName"])){
1064 $display= $Entry["sn"][0].", ".$Entry["givenName"][0]." [".$Entry["uid"][0]."]";
1065 } else {
1066 $display= "[".$Entry["uid"][0]."]";
1067 }
1069 $display = strtolower($display);
1070 $List[$display] = $Entry;
1071 $SortTemp[$display] = $display;
1072 }
1073 }
1074 natcasesort($SortTemp);
1075 reset($SortTemp);
1077 $this->list = array();
1078 foreach($SortTemp as $Key){
1079 $this->list[] = $List[$Key];
1080 }
1081 }
1084 function remove_lock()
1085 {
1086 /* Remove user lock if a DN is marked as "currently edited" */
1087 if (isset($this->usertab->dn)){
1088 del_lock ($this->usertab->dn);
1089 }elseif(isset($this->dn) && !empty($this->dn) && $this->dn != "new"){
1090 del_lock($this->dn);
1091 }
1092 if(isset($this->dns) && is_array($this->dns) && count($this->dns)){
1093 del_lock($this->dns);
1094 }
1095 }
1098 function copyPasteHandling_from_queue($s_action,$s_entry)
1099 {
1100 /* Check if Copy & Paste is disabled */
1101 if(!is_object($this->CopyPasteHandler)){
1102 return("");
1103 }
1105 $ui = get_userinfo();
1107 /* Add a single entry to queue */
1108 if($s_action == "cut" || $s_action == "copy"){
1110 /* Cleanup object queue */
1111 $this->CopyPasteHandler->cleanup_queue();
1112 $dn = $this->list[$s_entry]['dn'];
1113 if($s_action == "copy" && $ui->is_copyable($dn,"users","user")){
1114 $this->CopyPasteHandler->add_to_queue($dn,$s_action,"usertabs","USERTABS","users");
1115 }
1116 if($s_action == "cut" && $ui->is_cutable($dn,"users","user")){
1117 $this->CopyPasteHandler->add_to_queue($dn,$s_action,"usertabs","USERTABS","users");
1118 }
1119 }
1121 /* Add entries to queue */
1122 if($s_action == "copy_multiple" || $s_action == "cut_multiple"){
1124 /* Cleanup object queue */
1125 $this->CopyPasteHandler->cleanup_queue();
1127 /* Add new entries to CP queue */
1128 foreach($this->list_get_selected_items() as $id){
1129 $dn = $this->list[$id]['dn'];
1131 if($s_action == "copy_multiple" && $ui->is_copyable($dn,"users","user")){
1132 $this->CopyPasteHandler->add_to_queue($dn,"copy","usertabs","USERTABS","users");
1133 }
1134 if($s_action == "cut_multiple" && $ui->is_cutable($dn,"users","user")){
1135 $this->CopyPasteHandler->add_to_queue($dn,"cut","usertabs","USERTABS","users");
1136 }
1137 }
1138 }
1140 /* Start pasting entries */
1141 if($s_action == "editPaste"){
1142 $this->start_pasting_copied_objects = TRUE;
1143 }
1145 /* Return C&P dialog */
1146 if($this->start_pasting_copied_objects && $this->CopyPasteHandler->entries_queued()){
1148 /* Get dialog */
1149 $this->CopyPasteHandler->SetVar("base",$this->DivListUsers->selectedBase);
1150 $data = $this->CopyPasteHandler->execute();
1152 /* Set CPPasswordChange to s_entry which indicates that this entry requires a new password. */
1153 if(isset($_POST['passwordTodo']) && ($_POST['passwordTodo'] == "new")){
1154 $s_entry = $this->CopyPasteHandler->last_entry();
1155 $this->reload();
1156 foreach($this->list as $key => $entry){
1157 if($entry['dn'] == $s_entry){
1158 $this->CPPasswordChange = $key;
1159 }
1160 }
1161 }
1163 /* Return dialog data */
1164 if(!empty($data) && $this->CPPasswordChange == ""){
1165 return($data);
1166 }
1167 }
1169 /* Automatically disable status for pasting */
1170 if(!$this->CopyPasteHandler->entries_queued()){
1171 $this->start_pasting_copied_objects = FALSE;
1172 }
1173 return("");
1174 }
1177 function save_object()
1178 {
1179 /* Handle divlist filter && department selection*/
1180 if(!is_object($this->usertab)){
1181 $this->DivListUsers->save_object();
1182 }
1183 if(is_object($this->CopyPasteHandler)){
1184 $this->CopyPasteHandler->save_object();
1185 }
1186 }
1189 function list_get_selected_items()
1190 {
1191 $ids = array();
1192 foreach($_POST as $name => $value){
1193 if(preg_match("/^item_selected_[0-9]*$/",$name)){
1194 $id = preg_replace("/^item_selected_/","",$name);
1195 $ids[$id] = $id;
1196 }
1197 }
1198 return($ids);
1199 }
1202 /* A set of disabled and therefore overloaded functions. They are
1203 not needed in this class. */
1204 function remove_from_parent() { }
1205 function check() { }
1206 function save() { }
1207 function adapt_from_template($dn, $skip= array()) { }
1208 function password_change_needed() { }
1210 } /* ... class userManagement */
1211 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1212 ?>