1 <?php
2 /*
3 This code is part of GOsa (https://gosa.gonicus.de)
4 Copyright (C) 2003 Cajus Pollmeier
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
21 class groupManagement extends plugin
22 {
23 /* Definitions */
24 var $plHeadline= "Groups";
25 var $plDescription= "This does something";
27 /* Dialog attributes */
28 var $grouptab = NULL;
29 var $grouplist = array();
30 var $ui = NULL;
31 var $CopyPasteHandler = NULL;
32 var $DivListGroup = NULL;
33 var $ShowPrimaryCheckBox= false;
34 var $start_pasting_copied_objects = FALSE;
36 function groupManagement (&$config, &$ui)
37 {
38 /* Save configuration for internal use */
39 $this->config = &$config;
40 $this->ui = &$ui;
42 /* Copy & Paste enabled ?*/
43 if((isset($this->config->data['MAIN']['ENABLECOPYPASTE']))&&(preg_match("/true/i",$this->config->data['MAIN']['ENABLECOPYPASTE']))){
44 $this->CopyPasteHandler = new CopyPasteHandler($this->config);
45 }
47 /* Detect if we have to display the primary group checkbox */
48 $tmp = "";
49 if (isset($this->config->data['MAIN']['NOPRIMARYGROUP'])){
50 $tmp = $this->config->data['MAIN']['NOPRIMARYGROUP'];
51 }
52 if(preg_match("/true/i",$tmp)|| (preg_match("/yes/",$tmp))){
53 $this->ShowPrimaryCheckBox = false;
54 } else {
55 $this->ShowPrimaryCheckBox = true;
56 }
58 /* Create dialog object */
59 $this->DivListGroup = new divListGroup($this->config,$this);
60 $this->DivListGroup->DisableCheckBox("ShowPrimaryGroups",$this->ShowPrimaryCheckBox);
61 }
64 function execute()
65 {
66 /* Call parent execute */
67 plugin::execute();
69 /* Store these posts if the current object is locked (used by somebody else)*/
70 session::set('LOCK_VARS_TO_USE',array("/^act$/","/^id$/","/^group_edit_/","/^group_del_/","/^item_selected/","/^remove_multiple_groups/","/^multiple_edit/","/menu_action/"));
72 /* Save data */
73 $s_action = "";
74 $s_entry = "";
76 /* Test Posts */
77 foreach($_POST as $key => $val){
78 // Post for delete
79 if(preg_match("/^group_del.*/",$key)){
80 $s_action = "del";
81 $s_entry = preg_replace("/group_".$s_action."_/i","",$key);
82 // Post for edit
83 }elseif(preg_match("/^group_edit_.*/",$key)){
84 $s_action="edit";
85 $s_entry = preg_replace("/group_".$s_action."_/i","",$key);
86 // Post for new
87 }elseif(preg_match("/^group_new.*/",$key)){
88 $s_action="new";
89 }elseif(preg_match("/^dep_home.*/i",$key)){
90 $s_action="home";
91 }elseif(preg_match("/^group_tplnew.*/i",$key)){
92 $s_action="new_tpl";
93 }elseif(preg_match("/^group_chgpw.*/i",$key)){
94 $s_action="change_pw";
95 $s_entry = preg_replace("/group_chgpw_/i","",$key);
96 }elseif(preg_match("/_group_edit_/",$key)){
97 $type = preg_replace("/_group_edit_.*$/","",$key);
98 $s_action="edit";
99 $s_entry = preg_replace("/".$type."_group_edit_/i","",$key);
100 $_POST['arg'] = $type;
101 }elseif(preg_match("/^editPaste.*/i",$key)){
102 $s_action="editPaste";
103 }elseif(preg_match("/^copy_.*/",$key)){
104 $s_action="copy";
105 $s_entry = preg_replace("/^copy_/i","",$key);
106 }elseif(preg_match("/^cut_.*/",$key)){
107 $s_action="cut";
108 $s_entry = preg_replace("/^cut_/i","",$key);
109 }elseif(preg_match("/^remove_multiple_groups/",$key)){
110 $s_action="del_multiple";
111 }elseif(preg_match("/^multiple_copy_groups/",$key)){
112 $s_action = "copy_multiple";
113 }elseif(preg_match("/^multiple_cut_groups/",$key)){
114 $s_action = "cut_multiple";
115 }
116 }
117 $s_entry = preg_replace("/_.$/","",$s_entry);
119 /* Check for posted gets */
120 if((isset($_GET['act'])) && ($_GET['act'] == "edit_entry")){
121 $s_entry = $_GET['id'];
122 $s_action = "edit";
123 }
125 /* handle C&P from layers menu */
126 if(isset($_POST['menu_action']) && preg_match("/^multiple_copy_systems/",$_POST['menu_action'])){
127 $s_action = "copy_multiple";
128 }
129 if(isset($_POST['menu_action']) && preg_match("/^multiple_cut_systems/",$_POST['menu_action'])){
130 $s_action = "cut_multiple";
131 }
132 if(isset($_POST['menu_action']) && preg_match("/^editPaste/",$_POST['menu_action'])){
133 $s_action = "editPaste";
134 }
136 /* Create options */
137 if(isset($_POST['menu_action']) && $_POST['menu_action'] == "group_new"){
138 $s_action = "new";
139 }
141 /* handle remove from layers menu */
142 if(isset($_POST['menu_action']) && preg_match("/^remove_multiple/",$_POST['menu_action'])){
143 $s_action = "del_multiple";
144 }
145 if(isset($_POST['menu_action']) && $_POST['menu_action'] == "multiple_edit"){
146 $s_action = "multiple_edit";
147 }
150 $smarty= get_smarty();
152 /********************
153 Copy & Paste Handling ...
154 ********************/
156 /* Display the copy & paste dialog, if it is currently open */
157 $ret = $this->copyPasteHandling_from_queue($s_action,$s_entry);
158 if($ret){
159 return($ret);
160 }
163 /********************
164 Create a new group ...
165 ********************/
167 /* New group? */
168 if ($s_action=="new"){
170 /* Check create permissions */
171 $acl = $this->ui->get_permissions($this->DivListGroup->selectedBase,"groups/group");
172 if(preg_match("/c/",$acl)){
174 /* By default we set 'dn' to 'new', all relevant plugins will
175 react on this. */
176 $this->dn= "new";
178 /* Create new usertab object */
179 $this->grouptab= new grouptabs($this->config, $this->config->data['TABS']['GROUPTABS'], $this->dn);
181 /* Set up the group ACL's for this 'dn' */
182 $this->grouptab->set_acl_base($this->DivListGroup->selectedBase);
183 }
184 }
187 /********************
188 Save Group Tab/Object Changes
189 ********************/
191 /* Finish group edit is triggered by the tabulator dialog, so
192 the user wants to save edited data. Check and save at this
193 point. */
194 if ((isset($_POST['edit_finish']) || isset($_POST['edit_apply'])) && (isset($this->grouptab->config)) ){
196 /* Check tabs, will feed message array
197 Save, or display error message? */
198 $message= $this->grouptab->check();
199 if (count($message) == 0){
201 /* Save user data to ldap */
202 $this->grouptab->save();
204 if (!isset($_POST['edit_apply'])){
205 /* Group has been saved successfully, remove lock from LDAP. */
206 if ($this->dn != "new"){
207 del_lock ($this->dn);
208 }
210 /* There's no page reload so we have to read new groups at this point. */
211 //$this->reload ();
212 unset ($this->grouptab);
213 $this->grouptab= NULL;
214 session::un_set('objectinfo');
215 }
216 } else {
217 /* Ok. There seem to be errors regarding to the tab data,
218 show message and continue as usual. */
219 show_errors($message);
220 }
221 }
224 /********************
225 Edit multiple entries
226 ********************/
228 /* User wants to edit data? */
229 if ($s_action == "multiple_edit" && !isset($this->grouptab->config)){
231 $this->dn = array();
232 foreach($this->list_get_selected_items() as $id){
233 $this->dn[] = $this->grouplist[$id]['dn'];;
234 }
235 $tmp = new multi_plug($this->config,"grouptabs",$this->config->data['TABS']['GROUPTABS'],
236 $this->dn,$this->DivListGroup->selectedBase,"groups");
237 if ($tmp->entries_locked()){
238 return($tmp->display_lock_message());
239 }
240 $tmp->lock_entries($this->ui->dn);
241 if($tmp->multiple_available()){
242 $this->grouptab = $tmp;
243 session::set('objectinfo',$this->grouptab->get_object_info());
244 }
245 }
248 /********************
249 Edit existing group
250 ********************/
252 /* User wants to edit data? */
253 if (($s_action=="edit") && (!isset($this->grouptab-> config))){
255 /* Get 'dn' from posted 'uid', must be unique */
256 $this->dn= $this->grouplist[trim($s_entry)]['dn'];
258 /* Check locking & lock entry if required */
259 $user = get_lock($this->dn);
260 if ($user != ""){
261 return(gen_locked_message ($user, $this->dn));
262 }
263 add_lock ($this->dn, $this->ui->dn);
265 /* Register grouptab to trigger edit dialog */
266 $this->grouptab= new grouptabs($this->config,$this->config->data['TABS']['GROUPTABS'], $this->dn);
267 $this->grouptab->set_acl_base($this->dn);
268 session::set('objectinfo',$this->dn);
269 }
272 /********************
273 Delete MULTIPLE entries requested, display confirm dialog
274 ********************/
276 if ($s_action=="del_multiple"){
277 $ids = $this->list_get_selected_items();
279 if(count($ids)){
281 foreach($ids as $id){
282 $dn = $this->grouplist[$id]['dn'];
283 if (($user= get_lock($dn)) != ""){
284 return(gen_locked_message ($user, $dn));
285 }
286 $this->dns[$id] = $dn;
287 }
289 $dns_names = "<br><pre>";
290 foreach($this->dns as $dn){
291 add_lock ($dn, $this->ui->dn);
292 $dns_names .= $dn."\n";
293 }
294 $dns_names .="</pre>";
296 /* Lock the current entry, so nobody will edit it during deletion */
297 if (count($this->dns) == 1){
298 $smarty->assign("info", sprintf(_("You're about to delete the following entry %s"), @LDAP::fix($dns_names)));
299 } else {
300 $smarty->assign("info", sprintf(_("You're about to delete the following entries %s"), @LDAP::fix($dns_names)));
301 }
302 $smarty->assign("multiple", true);
303 return($smarty->fetch(get_template_path('remove.tpl', TRUE)));
304 }
305 }
308 /********************
309 Delete MULTIPLE entries confirmed
310 ********************/
312 /* Confirmation for deletion has been passed. Groups should be deleted. */
313 if (isset($_POST['delete_multiple_groups_confirm'])){
315 /* Remove user by user and check acls before removeing them */
316 foreach($this->dns as $key => $dn){
318 /* Load permissions for selected 'dn' and check if
319 we're allowed to remove this 'dn' */
320 $acl = $this->ui->get_permissions($dn,"groups/group");
321 if(preg_match("/d/",$acl)){
323 /* Delete request is permitted, perform LDAP action */
324 $this->grouptab= new grouptabs($this->config,$this->config->data['TABS']['GROUPTABS'], $dn);
325 $this->grouptab->set_acl_base($dn);
326 $this->grouptab->delete ();
327 unset ($this->grouptab);
328 $this->grouptab= NULL;
330 } else {
332 /* Normally this shouldn't be reached, send some extra
333 logs to notify the administrator */
334 msg_dialog::display(_("Permission error"), _("You have no permission to delete this entry!"), ERROR_DIALOG);
335 new log("security","groups/".get_class($this),$dn,array(),"Tried to trick deletion.");
336 }
337 /* Remove lock file after successfull deletion */
338 del_lock ($dn);
339 unset($this->dns[$key]);
340 }
341 }
344 /********************
345 Delete MULTIPLE entries Canceled
346 ********************/
348 /* Remove lock */
349 if(isset($_POST['delete_multiple_user_cancel'])){
350 foreach($this->dns as $key => $dn){
351 del_lock ($dn);
352 unset($this->dns[$key]);
353 }
354 }
357 /********************
358 Delete group
359 ********************/
361 /* Remove group was requested */
362 if ($s_action=="del"){
364 /* Get 'dn' from posted 'uid' */
365 $this->dn= $this->grouplist[trim($s_entry)]['dn'];
367 /* Load permissions for selected 'dn' and check if
368 we're allowed to remove this 'dn' */
369 $acl = $this->ui->get_permissions($this->dn,"groups/group");
370 if(preg_match("/d/",$acl)){
372 /* Check locking, save current plugin in 'back_plugin', so
373 the dialog knows where to return. */
374 if (($user= get_lock($this->dn)) != ""){
375 return(gen_locked_message ($user, $this->dn));
376 }
378 /* Lock the current entry, so nobody will edit it during deletion */
379 add_lock ($this->dn, $this->ui->dn);
380 $smarty->assign("info", sprintf(_("You're about to delete the group '%s'."), @LDAP::fix($this->dn)));
381 $smarty->assign("multiple", false);
382 return($smarty->fetch(get_template_path('remove.tpl', TRUE)));
384 } else {
386 /* Obviously the user isn't allowed to delete. Show message and clean session. */
387 msg_dialog::display(_("Permission error"), _("You have no permission to delete this entry!"), ERROR_DIALOG);
388 }
389 }
392 /********************
393 Delete group confirmed
394 ********************/
396 /* Confirmation for deletion has been passed. Group should be deleted. */
397 if (isset($_POST['delete_group_confirm'])){
399 /* Some nice guy may send this as POST, so we've to check
400 for the permissions again. */
401 $acl = $this->ui->get_permissions($this->dn,"groups/group");
402 if(preg_match("/d/",$acl)){
404 /* Delete request is permitted, perform LDAP action */
405 $this->grouptab= new grouptabs($this->config,$this->config->data['TABS']['GROUPTABS'], $this->dn);
406 $this->grouptab->set_acl_base($this->dn);
407 $this->grouptab->delete ();
408 unset ($this->grouptab);
409 $this->grouptab= NULL;
411 /* Group list has changed, reload it. */
412 //$this->reload ();
414 } else {
416 /* Normally this shouldn't be reached, send some extra
417 logs to notify the administrator */
418 msg_dialog::display(_("Permission error"), _("You have no permission to delete this entry!"), ERROR_DIALOG);
419 new log("security","groups/".get_class($this),$dn,array(),"Tried to trick deletion.");
420 }
422 /* Remove lock file after successfull deletion */
423 del_lock ($this->dn);
424 session::un_set('objectinfo');
425 }
428 /********************
429 Delete group canceled
430 ********************/
432 /* Delete group canceled? */
433 if (isset($_POST['delete_cancel'])){
434 del_lock ($this->dn);
435 session::un_set('objectinfo');
436 }
439 /********************
440 A dialog was canceled
441 ********************/
443 /* Cancel dialogs */
444 if (isset($_POST['edit_cancel']) || isset($_POST['password_cancel'])){
445 if(isset($this->grouptab->dn)){
446 del_lock ($this->grouptab->dn);
447 }
448 unset ($this->grouptab);
449 $this->grouptab= NULL;
450 session::un_set('objectinfo');
451 }
454 /********************
455 If there is currently a dialog open, display it
456 ********************/
458 /* Show tab dialog if object is present */
459 if (isset($this->grouptab->config)){
460 $display= $this->grouptab->execute();
462 /* Don't show buttons if tab dialog requests this */
463 if(isset($this->grouptab->by_object)){
464 if (!$this->grouptab->by_object[$this->grouptab->current]->dialog){
465 $display.= "<p style=\"text-align:right\">\n";
466 $display.= "<input type=submit name=\"edit_finish\" style=\"width:80px\" value=\""._("Ok")."\">\n";
467 $display.= " \n";
468 if ($this->dn != "new"){
469 $display.= "<input type=submit name=\"edit_apply\" value=\""._("Apply")."\">\n";
470 $display.= " \n";
471 }
472 $display.= "<input type=submit name=\"edit_cancel\" value=\""._("Cancel")."\">\n";
473 $display.= "</p>";
474 }
475 }
476 return ($display);
477 }
480 /* Check if there is a snapshot dialog open */
481 $base = $this->DivListGroup->selectedBase;
482 if($str = $this->showSnapshotDialog($base,$this->get_used_snapshot_bases())){
483 return($str);
484 }
486 /* Display dialog with group list */
487 $this->DivListGroup->parent = $this;
488 $this->DivListGroup->execute();
490 /* Add departments if subsearch is disabled */
491 if(!$this->DivListGroup->SubSearch){
492 $this->DivListGroup->AddDepartments($this->DivListGroup->selectedBase,4,1);
493 }
494 $this->reload ();
495 $this->DivListGroup->setEntries($this->grouplist);
496 return($this->DivListGroup->Draw());
497 }
500 /* Return departments, that will be included within snapshot detection */
501 function get_used_snapshot_bases()
502 {
503 return(array(get_groups_ou().$this->DivListGroup->selectedBase));
504 }
507 function list_get_selected_items()
508 {
509 $ids = array();
510 foreach($_POST as $name => $value){
511 if(preg_match("/^item_selected_[0-9]*$/",$name)){
512 $id = preg_replace("/^item_selected_/","",$name);
513 $ids[$id] = $id;
514 }
515 }
516 return($ids);
517 }
520 function reload($CreatePosixsList=false)
521 {
522 $this->grouplist = array();
523 $primaries = array();
524 $functional = array();
525 $error= $error2 = "";
526 $filter = "(objectclass=posixGroup)";
528 $base = $this->DivListGroup->selectedBase;
529 $Regex = $this->DivListGroup->Regex;
530 $UserRegex = $this->DivListGroup->UserRegex;
531 $SubSearch = $this->DivListGroup->SubSearch;
532 $ShowPrimaryGroups = $this->DivListGroup->ShowPrimaryGroups;
533 $ShowSambaGroups = $this->DivListGroup->ShowSambaGroups;
534 $ShowApplicationGroups = $this->DivListGroup->ShowApplicationGroups;
535 $ShowMailGroups = $this->DivListGroup->ShowMailGroups;
536 $ShowFunctionalGroups = $this->DivListGroup->ShowFunctionalGroups;
538 /* Prepare ldap class */
539 $ldap= $this->config->get_ldap_link();
540 $ldap->cd($base);
541 $ldap->set_size_limit(session::get('size_limit'));
544 /********************
545 Create filter depending on selected checkboxes
546 ********************/
548 /* Add application groups */
549 if ($ShowApplicationGroups){
550 $filter.= "(objectClass=gosaApplicationGroup)";
551 }
553 /* Add Mail Groups */
554 if ($ShowMailGroups){
555 $filter.= "(objectClass=gosaMailAccount)";
556 }
558 $sfilter= "";
559 if ($this->config->current['SAMBAVERSION'] == 3){
560 if (!$ShowPrimaryGroups){
561 $sfilter= "(objectClass=sambaGroupMapping)";
562 } elseif ($ShowSambaGroups){
563 $filter.= "(objectClass=sambaGroupMapping)";
564 }
565 }
567 /* Prepare filter for given Regex && UserRegex */
568 if ($filter != ""){
569 $filter= "(&(cn=$Regex)(objectClass=posixGroup)(|$filter))";
570 if ($UserRegex != ""){
571 $filter= "(&(|(memberUID=".$UserRegex.")(cn=".$UserRegex."))$filter)";
572 }
573 }
576 /********************
577 Collect some groupids to be able to skip primary & functional groups
578 ********************/
580 /* Collect primary groupIDs to show primary groups
581 if this option is enabled in gosa conf && the checkbox is checked */
582 if ($this->ShowPrimaryCheckBox){
583 $res = get_list("(&(uid=$Regex)(!(uid=*$))(objectClass=posixAccount)(gidNumber=*))",
584 "groups", $base,array("gidNumber", "cn"), GL_SUBSEARCH);
585 foreach ($res as $attrs){
586 $primaries[$attrs['gidNumber'][0]]= $attrs['cn'][0];
587 }
588 }
590 /* Collect all GroupIDs from those groups which are functional.
591 Only perfrom this search if ShowFunctionalGroups is unchecked, else leave arre empty */
592 $ff = "(&(cn=$Regex)(objectClass=posixGroup)(!(|(objectClass=gosaMailAccount)(objectClass=gosaApplicationGroup)$sfilter)))";
593 if ($SubSearch){
594 $res = get_sub_list($ff, "groups",get_groups_ou(), $base,array("gidNumber", "cn", "description"), GL_SUBSEARCH);
595 } else {
596 $res = get_sub_list($ff, "groups",get_groups_ou(), $base,array("gidNumber", "cn", "description"), GL_NONE);
597 }
598 foreach($res as $attrs){
599 if (!isset($primaries[$attrs['gidNumber'][0]])){
600 $functional[$attrs['gidNumber'][0]]= $attrs['gidNumber'][0];
601 }
602 }
604 /********************
605 Search for the prepared filter
606 ********************/
608 /* Attributes to search for */
609 $attrs = array("cn", "description", "gidNumber", "objectClass");
611 /* If subsearch is activated search for subobjects too */
612 $tmp = $this->config->search("faiManagement", "CLASS",array('menu','tabs'));
613 if(!empty($tmp)){
614 $attrs [] = "FAIrelease";
615 }
617 if ($SubSearch){
618 $res= get_sub_list($filter, "groups",get_groups_ou(), $base, $attrs, GL_SIZELIMIT| GL_SUBSEARCH);
619 } else {
620 $res= get_sub_list($filter, "groups",get_groups_ou(), get_groups_ou().$base, $attrs, GL_SIZELIMIT);
621 }
623 /* Sort values into grouplist*/
624 $tmp = $tmp2 = array();
625 foreach ($res as $value){
626 /* Skip functional groups if checkbox isn't checked */
627 if (!$ShowFunctionalGroups && isset($functional[$value['gidNumber'][0]])){
628 continue;
629 }
631 /* If gidNumber is in $primaries skip this entry */
632 if (($ShowPrimaryGroups) || (!$ShowPrimaryGroups && !isset($primaries[$value['gidNumber'][0]]))){
633 $tmp2[$value['cn'][0]] = $value;
634 $tmp [$value['cn'][0]] = $value['cn'][0];
635 }
636 }
637 natcasesort($tmp);
638 foreach($tmp as $name){
639 $this->grouplist[] = $tmp2[$name];
640 }
641 reset ($this->grouplist);
642 }
645 function copyPasteHandling_from_queue($s_action,$s_entry)
646 {
647 /* Check if Copy & Paste is disabled */
648 if(!is_object($this->CopyPasteHandler)){
649 return("");
650 }
652 /* Add a single entry to queue */
653 if($s_action == "cut" || $s_action == "copy"){
655 /* Cleanup object queue */
656 $this->CopyPasteHandler->cleanup_queue();
657 $dn = $this->grouplist[$s_entry]['dn'];
658 $this->CopyPasteHandler->add_to_queue($dn,$s_action,"grouptabs","GROUPTABS","groups");
659 }
662 /* Add entries to queue */
663 if($s_action == "copy_multiple" || $s_action == "cut_multiple"){
665 /* Cleanup object queue */
666 $this->CopyPasteHandler->cleanup_queue();
668 /* Add new entries to CP queue */
669 foreach($this->list_get_selected_items() as $id){
670 $dn = $this->grouplist[$id]['dn'];
672 if($s_action == "copy_multiple"){
673 $this->CopyPasteHandler->add_to_queue($dn,"copy","grouptabs","GROUPTABS","groups");
674 }
675 if($s_action == "cut_multiple"){
676 $this->CopyPasteHandler->add_to_queue($dn,"cut","grouptabs","GROUPTABS","groups");
677 }
678 }
679 }
681 /* Start pasting entries */
682 if($s_action == "editPaste"){
683 $this->start_pasting_copied_objects = TRUE;
684 }
686 /* Return C&P dialog */
687 if($this->start_pasting_copied_objects && $this->CopyPasteHandler->entries_queued()){
689 /* Load entry from queue and set base */
690 $this->CopyPasteHandler->load_entry_from_queue();
691 $this->CopyPasteHandler->SetVar("base",$this->DivListGroup->selectedBase);
693 /* Get dialog */
694 $data = $this->CopyPasteHandler->execute();
696 /* Return dialog data */
697 if(!empty($data)){
698 return($data);
699 }
700 }
702 /* Automatically disable status for pasting */
703 if(!$this->CopyPasteHandler->entries_queued()){
704 $this->start_pasting_copied_objects = FALSE;
705 }
706 return("");
707 }
710 /* Save data to object */
711 function save_object()
712 {
713 $this->DivListGroup->save_object();
714 }
717 function remove_lock()
718 {
719 if (isset($this->grouptab->dn)){
720 del_lock ($this->grouptab->dn);
721 }
722 }
725 function remove_from_parent()
726 {
727 /* Optionally execute a command after we're done */
728 $this->postremove();
729 }
732 /* Save to LDAP */
733 function save()
734 {
735 /* Optionally execute a command after we're done */
736 $this->postcreate();
737 }
739 /* Unused functions */
740 function check() { }
741 function adapt_from_template($dn) { }
742 function password_change_needed() { }
743 }
744 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
745 ?>