Code

Added base selector to groups and users
[gosa.git] / gosa-core / plugins / admin / groups / class_group.inc
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 group extends plugin
24 {
25   /* Group attributes */
26   var $cn= "";
27   var $description= "";
28   var $gidNumber= "";
29   var $memberUid= array();
30   var $memberUid_used_by_some= array();
32   /* Helpers */
33   var $base= "";
34   var $force_gid= FALSE;
35   var $fon_group= FALSE;
36   var $smbgroup= FALSE;
37   var $groupType= FALSE;
38   var $sambaSID= "";
39   var $sambaDomainName= "DEFAULT";
40   var $SID= "";
41   var $ridBase= 0;
42   var $members= array();
43   var $users= array();
44   var $member= array();
45   var $allusers= array();
46   var $saved_gidNumber= "";
47   var $oldgroupType= "";
48   var $orig_dn= "";
49   var $orig_cn= "";
50   var $orig_base= "";
51   var $has_mailAccount= FALSE;
52   var $userSelect= FALSE;
53   var $nagios_group =FALSE;
54   var $sambaGroupType;
55   var $dialog;
56   var $rfc2307bis= FALSE;
57   var $OnlyShowFirstEntries =200;
58   var $dnMapping= array();
59   var $view_logged = FALSE;
60   var $allowGroupsWithSameNameInOtherSubtrees = true;
61   var $baseSelector;
63   /* Trustmodel/AccessTo 
64    */
65   var $accessTo= array();
66   var $trustModel= "";
67   var $trustSelect = FALSE;
69   /* attribute list for save action */
70   var $attributes= array("cn", "description", "gidNumber","memberUid","sambaGroupType","sambaSID","accessTo","trustModel");
71   var $objectclasses= array("top", "posixGroup");
73   var $CopyPasteVars  = array("force_gid","fon_group","smbgroup","groupType","sambaSID","sambaDomainName","SID","nagios_group","sambaGroupType");
75   var $multiple_support = TRUE;
77   function group (&$config, $dn= NULL)
78   {
79      /* Set rfc2307bis flag */
80      if ($config->get_cfg_value("rfc2307bis") == "true"){
81        $this->rfc2307bis= TRUE;
82        $this->attributes[]= "member";
83        $this->objectclasses[]= "groupOfNames";
84      }
86     plugin::plugin ($config, $dn);
88     /* Load attributes depending on the samba version */
89     $this->orig_dn= $dn;
90     $this->orig_cn= $this->cn;
92     /* Get member list */
93     if (isset($this->attrs['memberUid'][0])){
94       $tmp= array();
95       for ($i= 0; $i<$this->attrs['memberUid']['count']; $i++){
96         $tmp[$this->attrs['memberUid'][$i]]= $this->attrs['memberUid'][$i];
97       }
98       $this->memberUid= $tmp;
99       ksort ($this->memberUid);
100     }
102     /* Save gidNumber for later use */
103     if (isset($this->attrs['gidNumber'])){
104       $this->saved_gidNumber= $this->attrs['gidNumber'][0];
105     }
107     /* Is a samba group? */
108     if (isset($this->attrs['objectClass'])){
109       if (array_search ('sambaGroupMapping', $this->attrs['objectClass']) == FALSE ){
110         $this->smbgroup= FALSE;
111       } else {
112         $this->smbgroup= TRUE;
113         if (isset($this->attrs['sambaSID'])){
114           $this->sambaSID= $this->attrs['sambaSID'][0];
115         }
116       }
117       if (array_search ('goFonPickupGroup', $this->attrs['objectClass']) == FALSE ){
118         $this->fon_group= FALSE;
119       } else {
120         $this->fon_group= TRUE;
121       }
122       if (array_search ('nagiosContactGroup', $this->attrs['objectClass']) == FALSE ){
123         $this->nagios_group= FALSE;
124       } else {
125         $this->nagios_group= TRUE;
126       }
127     }
129     /* Set mail flag */
130     if (isset($this->attrs['objectClass']) && in_array('gosaMailAccount', $this->attrs['objectClass'])){
131       $this->has_mailAccount= TRUE;
132     }
134     /* Get samba Domain in case of samba 3 */
135     if ($this->sambaSID != ""){
136       $this->SID= preg_replace ("/-[^-]+$/", "", $this->sambaSID);
137       $ldap= $this->config->get_ldap_link();
138       $ldap->cd($this->config->current['BASE']);
139       $ldap->search ("(&(objectClass=sambaDomain)(sambaSID=$this->SID))",array("sambaAlgorithmicRidBase"));
140       if ($ldap->count() != 0){
141         $attrs= $ldap->fetch();
142         if(isset($attrs['sambaAlgorithmicRidBase'])){  
143           $this->ridBase= $attrs['sambaAlgorithmicRidBase'][0];  
144         } else {  
145           $this->ridBase= $this->config->get_cfg_value("sambaRidBase");
146         } 
148         /* Get domain name for SID */
149         $this->sambaDomainName= "DEFAULT";
150         foreach ($this->config->data['SERVERS']['SAMBA'] as $key => $val){
151           if ($val['SID'] == $this->SID){
152             $this->sambaDomainName= $key;
153             break;
154           }
155         }
156       } else {
157         if ($this->config->get_cfg_value("sambaRidBase") != ""){
158           $this->sambaDomainName= "DEFAULT";
159           $this->ridBase= $this->config->get_cfg_value("sambaRidBase");
160           $this->SID= $this->config->get_cfg_value("sid");
161         } else {
162           msg_dialog::display(_("Configuration error"), _("Cannot find group SID in your configuration!"), ERROR_DIALOG);
163         }
164       }
166       /* Get group type */
167       $this->groupType= (int)substr(strrchr($this->sambaSID, "-"), 1);
168       if ($this->groupType < 500 || $this->groupType > 553){
169         $this->groupType= 0;
170       }
171       $this->oldgroupType= $this->groupType;
172     }
174     /* Get global filter config */
175     if (!session::is_set("gufilter")){
176       $ui= get_userinfo();
177       $base= get_base_from_people($ui->dn);
178       $gufilter= array( "dselect"       => $base,
179           "regex"           => "*");
180       session::set("gufilter", $gufilter);
181     }
182     $gufilter= session::get('gufilter');
183     $gufilter['SubSearchGroup'] = false;
184     session::set('gufilter',$gufilter);
185   
186     if ($this->dn == "new"){
187       if(session::is_set('CurrentMainBase')){
188         $this->base = session::get('CurrentMainBase');
189       }else{
190         $ui= get_userinfo();
191         $this->base= dn2base($ui->dn);
192       }
193     } else {
195       /* Get object base */
196       $this->base =preg_replace ("/^[^,]+,".preg_quote(get_groups_ou(), '/')."/i","",$this->dn);
197     }
198     $this->orig_base = $this->base;
200     /* Is this account a trustAccount? */
201     if (isset($this->attrs['trustModel'])){
202       $this->trustModel= $this->attrs['trustModel'][0];
203       $this->was_trust_account= TRUE;
204     } else {
205       $this->was_trust_account= FALSE;
206       $this->trustModel= "";
207     }
209     $this->accessTo = array();
210     if (isset($this->attrs['accessTo'])){
211       for ($i= 0; $i<$this->attrs['accessTo']['count']; $i++){
212         $tmp= $this->attrs['accessTo'][$i];
213         $this->accessTo[$tmp]= $tmp;
214       }
215     }
217     /* Get global filter config */
218     if (!session::is_set("sysfilter")){
219       $ui= get_userinfo();
220       $base= get_base_from_people($ui->dn);
221       $sysfilter= array( "depselect"       => $base,
222           "regex"           => "*");
223       session::set("sysfilter", $sysfilter);
224     }
226     /* This is always an account */
227     $this->is_account= TRUE;
229     /* Instanciate base selector */
230     $this->baseSelector= new baseSelector($this->get_allowed_bases(), $this->base);
231     $this->baseSelector->setSubmitButton(false);
232     $this->baseSelector->setHeight(300);
233     $this->baseSelector->update(true);
235     $this->reload(TRUE);
236   }
238   function execute()
239   {
240     /* Call parent execute */
241     plugin::execute();
243     /* Log view */
244     if($this->is_account && !$this->view_logged){
245       $this->view_logged = TRUE;
246       new log("view","groups/".get_class($this),$this->dn);
247     }
249     /* Do we represent a valid group? */
250     if (!$this->is_account && $this->parent === NULL){
251       $display= "<img alt=\"\" src=\"images/small-error.png\" align=\"middle\">&nbsp;<b>".msgPool::noValidExtension()."</b>";
252       return ($display);
253     }
255     /* Delete user from group */
256     if (isset($_POST['del_users']) && isset($_POST['members']) && preg_match("/w/",$this->getacl("memberUid"))){
257       foreach ($_POST['members'] as $value){
258         unset ($this->members["$value"]);
259         $this->removeUser($value);
260       }
261       $this->reload();
262     }
264     /* Add objects? */
265     if (isset($_POST["edit_membership"]) && preg_match("/w/",$this->getacl("memberUid"))){
266       $this->userSelect= new userSelect($this->config, get_userinfo());
267       $this->dialog= TRUE;
268     }
270     /* Add objects finished? */
271     if (isset($_POST["add_users_cancel"])){
272       $this->userSelect= NULL;
273       $this->dialog= FALSE;
274     }
276     /* Add user to group */
277     if (isset($_POST['add_users_finish']) && $this->userSelect){
278   
279       $users = $this->userSelect->detectPostActions();
280       if(isset($users['targets'])){
281         $headpage = $this->userSelect->getHeadpage();
282         foreach($users['targets'] as $dn){
283           $attrs = $headpage->getEntry($dn);
284           $value = $attrs['uid'][0];
285           $this->addUser($value);
286           $this->members["$value"]= $this->allusers[$value];
287           $this->reload();
288         }
289       }
290       $this->userSelect= NULL;
291       $this->dialog= FALSE;
292     }
294     /* Base select dialog */
295     $once = true;
296     foreach($_POST as $name => $value){
297       if((preg_match("/^chooseBase/",$name) && $once) && $this->acl_is_writeable("base")){
298           
299         $once = false;
300         $this->dialog = new baseSelectDialog($this->config,$this,$this->get_allowed_bases());
301         $this->dialog->setCurrentBase($this->base);
302       }
303     }
305     /* Dialog handling */
306     if(is_object($this->dialog)){
307       /* Must be called before save_object */
308       $this->dialog->save_object();
310       if($this->dialog->isClosed()){
311         $this->dialog = false;
312       }elseif($this->dialog->isSelected()){
314         /* Check if selected base is valid */
315         $tmp = $this->get_allowed_bases();
316         if(isset($tmp[$this->dialog->isSelected()])){
317           $this->base = $this->dialog->isSelected();
318         }
319         $this->dialog= false;
320       }else{
321         return($this->dialog->execute());
322       }
323     }
326     /* Add user workstation? */
327     if (isset($_POST["add_ws"])){
328       $this->trustSelect= new trustSelect($this->config,get_userinfo());
329       $this->dialog= TRUE;
330     }
332     // Add selected machines to trusted ones.
333     if (isset($_POST["add_ws_finish"]) &&  $this->trustSelect){
334       $trusts = $this->trustSelect->detectPostActions();
335       if(isset($trusts['targets'])){
337         $headpage = $this->trustSelect->getHeadpage();
338         foreach($trusts['targets'] as $id){
339           $attrs = $headpage->getEntry($id);
340           $this->accessTo[$attrs['cn'][0]]= $attrs['cn'][0];
341         }
342         ksort($this->accessTo);
343         $this->is_modified= TRUE;
344       }
345       $this->trustSelect= NULL;
346       $this->dialog= FALSE;
347     }
350     /* Add user workstation? */
351     if (isset($_POST["add_ws_finish"]) && isset($_POST['wslist'])){
352       foreach($_POST['wslist'] as $ws){
353         $this->accessTo[$ws]= $ws;
354       }
355       ksort($this->accessTo);
356       $this->is_modified= TRUE;
357     }
359     /* Remove user workstations? */
360     if (isset($_POST["delete_ws"]) && isset($_POST['workstation_list'])){
361       foreach($_POST['workstation_list'] as $name){
362         unset ($this->accessTo[$name]);
363       }
364       $this->is_modified= TRUE;
365     }
367     /* Add user workstation finished? */
368     if (isset($_POST["add_ws_cancel"])){
369       $this->trustSelect= NULL;
370       $this->dialog= FALSE;
371     }
374     /* Show ws dialog */
375     if ($this->trustSelect){
376     
377       // Build up blocklist
378       session::set('filterBlacklist', array('cn' => array_values($this->accessTo)));
379       return($this->trustSelect->execute());
380     }
382     $smarty= get_smarty();
383     $smarty->assign("usePrototype", "true");
385     if($this->config->search("nagiosaccount", "CLASS",array('menu'))){
386       $smarty->assign("nagios",true);
387     }else{
388       $smarty->assign("nagios",false);
389     }
390     
391     if($this->config->search("phoneAccount", "CLASS",array('menu'))){
392       $smarty->assign("pickupGroup",true);
393     }else{
394       $smarty->assign("pickupGroup",false);
395     }
397     /* Manage object add dialog */
398     if ($this->userSelect){
399       return($this->userSelect->execute());
400     }
402     /* Create base acls */
403     $smarty->assign("base", $this->baseSelector->render());
405     $domains= array();
406     foreach($this->config->data['SERVERS']['SAMBA'] as $name => $content){
407       $domains[$name]= $name;
408     }
409     $smarty->assign("sambaDomains", $domains);
410     $smarty->assign("sambaDomainName", $this->sambaDomainName);
411     $groupTypes= array(0 => _("Samba group"), 512 => _("Domain admins"), 513 => _("Domain users"),
412         514 => _("Domain guests"));
414     /* Don't loose special groups! If not key'ed above, add it to
415        the combo box... */      
416     if ($this->groupType >= 500 && $this->groupType <= 553 && !isset($groupTypes[$this->groupType])){
417       $groupTypes[$this->groupType]= sprintf(_("Special group (%d)"), $this->groupType);
418     }
420     $smarty->assign("groupTypes", $groupTypes);
421     $smarty->assign("groupType", $this->groupType);
422     
424     /* Members and users */
425     $smarty->assign("members", $this->members);
427     /* Work on trust modes */
428     $smarty->assign("trusthide", " disabled ");
429     $smarty->assign("trustmodeACL",  $this->getacl("trustModel"));
430     if ($this->trustModel == "fullaccess"){
431       $trustmode= 1;
432       // pervent double disable tag in html code, this will disturb our clean w3c html
433       $smarty->assign("trustmode",  $this->getacl("trustModel"));
435     } elseif ($this->trustModel == "byhost"){
436       $trustmode= 2;
437       $smarty->assign("trusthide", "");
438     } else {
439       // pervent double disable tag in html code, this will disturb our clean w3c html
440       $smarty->assign("trustmode",  $this->getacl("trustModel"));
441       $trustmode= 0;
442     }
443     $smarty->assign("trustmode", $trustmode);
444     $smarty->assign("trustmodes", array( 0 => _("disabled"), 1 => _("full access"),
445           2 => _("allow access to these hosts")));
447     if((count($this->accessTo))==0){
448       $smarty->assign("emptyArrAccess",true);
449     } else{
450       $smarty->assign("emptyArrAccess",false);
452     }
454     $smarty->assign("workstations", $this->accessTo);
458     /* Checkboxes */
459     foreach (array("force_gid", "smbgroup") as $val){
460       if ($this->$val == "1"){
461         $smarty->assign("$val", "checked");
462       } else {
463         $smarty->assign("$val", "");
464       }
465     }
466     if ($this->force_gid != "1"){
467       $smarty->assign("forceMode", "disabled");
468     }else{
469       $smarty->assign("forceMode", "");
470     }
471     if ($this->fon_group){
472       $smarty->assign("fon_group", "checked");
473     } else {
474       $smarty->assign("fon_group", "");
475     }
477     if ($this->nagios_group){
478       $smarty->assign("nagios_group", "checked");
479     } else {
480       $smarty->assign("nagios_group", "");
481     }
483     /* Fields */
484     foreach (array("cn", "description", "gidNumber") as $val){
485       $smarty->assign("$val", $this->$val);
486     }
488     $tmp = $this->plInfo();
489     foreach($tmp['plProvidedAcls'] as $name => $translation){
490       $smarty->assign($name."ACL",$this->getacl($name));
491     }
492     
493     if($this->acl_is_writeable("base")){
494       $smarty->assign("baseSelect",true);
495     }else{
496       $smarty->assign("baseSelect",false);
497     }
499     /* Show main page */
500     $smarty->assign("alphabet", generate_alphabet(10));
501     $smarty->assign("search_image", get_template_path('images/lists/search.png'));
502     $smarty->assign("launchimage", get_template_path('images/lists/action.png'));
503     $smarty->assign("tree_image", get_template_path('images/lists/search-subtree.png'));
504     $smarty->assign("deplist", $this->config->idepartments);
506     /* Multiple edit handling */
507     $smarty->assign("multiple_support",$this->multiple_support_active);
509     $smarty->assign("memberUid_All",$this->memberUid);
510     $smarty->assign("memberUid_Some",$this->memberUid_used_by_some);
512     foreach($this->attributes as $val){
513       if(in_array($val,$this->multi_boxes)){
514         $smarty->assign("use_".$val,TRUE);
515       }else{
516         $smarty->assign("use_".$val,FALSE);
517       }
518     }
519     foreach(array("base","smbgroup","groupType","sambaDomainName","fon_group","nagios_group","trustmode") as $val){
520       if(in_array($val,$this->multi_boxes)){
521         $smarty->assign("use_".$val,TRUE);
522       }else{
523         $smarty->assign("use_".$val,FALSE);
524       }
525     }
527     return($smarty->fetch (get_template_path('generic.tpl', TRUE)));
528   }
530   function addUser($uid)
531   {
532     /* In mutliple edit we have to handle two arrays.
533      *  memberUid               : Containing users used in all groups
534      *  memberUid_used_by_some  : Those which are not used in all groups
535      * So we have to remove the given $uid from the ..used_by_some array first.
536      */
537     if($this->multiple_support_active){
538       if(isset($this->memberUid_used_by_some[$uid])){
539         unset($this->memberUid_used_by_some[$uid]);
540       }
541     }  
543     /* Ensure that the requested object is known to the group class 
544      */
545     if(!isset($this->dnMapping[$uid])){
546       $ldap = $this->config->get_ldap_link();
547       $ldap->cd($this->config->current['BASE']);
548       $ldap->search("(&(objectClass=gosaAccount)(uid=".$uid."))",array("dn", "uid","sn","givenName"));
549       if($ldap->count() == 0 ){
550         msg_dialog::display(_("Error"), 
551             sprintf(_("Adding UID '%s' to group '%s' failed: cannot find user object!"), 
552               $uid,$this->cn), 
553             ERROR_DIALOG);
554         return;
555       }elseif($ldap->count() >= 2){
556         msg_dialog::display(_("Error"), 
557             sprintf(_("Add UID '%s' to group '%s' failed: UID is used more than once!"),
558               $uid,$this->cn), 
559             ERROR_DIALOG);
560         return;
561       }else{
562         while($attrs = $ldap->fetch()){
563           $this->dnMapping[$attrs['uid'][0]] = $attrs['dn'];
564           $this->members[$attrs['uid'][0]] = $this->createResultName($attrs);
565           $this->allusers[$attrs['uid'][0]]= $this->createResultName($attrs);
566         }
567       }
568     }
570     $this->memberUid[$uid]= $uid;
571   }
574   function removeUser($uid)
575   {
576     $temp= array();
577     if(isset($this->memberUid[$uid])){
578       unset($this->memberUid[$uid]);
579     }
581     /* We have two array contianing group members in multiple edit.
582      *  this->memberUid             : Groups used by all currently edited groups 
583      *  this->memberUid_used_by_some: Used by some 
584      * So we have to remove the specified uid from both arrays.
585      */
586     if($this->multiple_support_active){
587       if(isset($this->memberUid_used_by_some[$uid])){
588         unset($this->memberUid_used_by_some[$uid]);
589       }
590     }
591   }
593   /* Reload data */
594   function reload($silent = FALSE)
595   {
596     /* Fix regex string */
597     $gufilter = session::get("gufilter");
598     $regex    = normalizeLdap($gufilter['regex']);
599     $MaxUser  = $this->OnlyShowFirstEntries;
601     /* Prepare ldap link */
602     $ldap= $this->config->get_ldap_link();
603     $ldap->cd($gufilter['dselect']);
606     /* Resolve still unresolved memberuids to fill the list with sn/giveName attributes 
607         (Store gathered sn/givenName informations in $this->allusers too, 
608          to be prepared when adding/deleting users)
609      */    
610     $filter = "";
611     if ($this->config->get_cfg_value("ldapFilterNestingLimit") == "" ||
612         count($this->memberUid) < $this->config->get_cfg_value("ldapFilterNestingLimit")){
613       foreach ($this->memberUid as $value){
614         if(!isset($this->members[$value])){
615           $filter .= "(uid=".normalizeLdap($value).")";
616         }
617       }
618     }
620     if(!empty($filter)){    
621       $ldap->cd($this->config->current['BASE']);
622       $ldap->search("(&(objectClass=gosaAccount)(|".$filter."))",array("dn", "uid","sn","givenName"));
623       while($attrs = $ldap->fetch()){
624         $this->dnMapping[$attrs['uid'][0]] = $attrs['dn'];
625         $this->members[$attrs['uid'][0]] = $this->createResultName($attrs);
626         $this->allusers[$attrs['uid'][0]]= $this->createResultName($attrs);
627       } 
628     }
629   
630     /* check if all uids are resolved */
631     if ($this->config->get_cfg_value("ldapFilterNestingLimit") == "" ||
632         count($this->memberUid) < $this->config->get_cfg_value("ldapFilterNestingLimit")){
633       foreach ($this->memberUid as $value){
634         if(!isset($this->members[$value])){
635           $this->members[$value] =  _("! unknown UID")." [".$value."]"; 
636         }
637       }  
638     }else{
639       foreach ($this->memberUid as $value){
640         $this->members[$value] = $value; 
641       }  
642     }
644     /* Create display list of users matching regex & filter 
645      */
646     $this->displayUsers = array();
647     $filter = "(&(objectClass=gosaAccount)(!(objectClass=gosaUserTemplate))(!(uid=*$))(|(uid=".$regex.")(sn=".$regex.")(givenName=".$regex.")))";
649     /* Search in current tree or within subtrees depending on the checkbox from filter section */
650     if($gufilter['SubSearchGroup']){
651       $flag = GL_SIZELIMIT | GL_SUBSEARCH;
652       $base = $gufilter['dselect'];
653     }else{
654       $flag = GL_SIZELIMIT ;
655       $base = get_people_ou().$gufilter['dselect'];
656     }
657     $i = 0;
658   
660     $res = get_list($filter,"users",$base,array("dn", "uid", "sn", "givenName"),$flag);
662     /* Fetch all users and skip already used users */
663     foreach($res as $attrs){
664       if(in_array($attrs['uid'][0], $this->memberUid)) {
665         continue;
666       }
667       $i ++;
668       if($i > $MaxUser) {
669         break;
670       }
671       $this->dnMapping[$attrs['uid'][0]]= $attrs["dn"];
672       $this->allusers[$attrs['uid'][0]]     = $this->createResultName($attrs);
673       $this->displayUsers[$attrs['uid'][0]] = $this->createResultName($attrs);
674     }
675   
676     /* If more than max users are found, display a message to warn the user */
677     if($i == $MaxUser && !$silent){
678       msg_dialog::display(_("Configuration error"), sprintf(_("Search returned too many results. Not displaying more than %s entries!"), $MaxUser), ERROR_DIALOG);
679     }
680     
681     /* Sort lists */
682     natcasesort($this->members);
683     reset($this->members);
684     natcasesort ($this->displayUsers);
685     reset ($this->displayUsers);
686   }
689   /* Create display name, this was used so often that it is excluded into a seperate function */
690   function createResultName($attrs)
691   {
692     if (isset($attrs["givenName"][0]) && isset($attrs["sn"][0])){
693       $ret =  $attrs["sn"][0].", ".$attrs["givenName"][0]." [".$attrs["uid"][0]."]";
694     } else {
695       $ret= $attrs['uid'][0];
696     }
697     return($ret);
698   }
701   function remove_from_parent()
702   {
703     plugin::remove_from_parent();
705     $ldap= $this->config->get_ldap_link();
706     $ldap->rmdir($this->dn);
707     if (!$ldap->success()){
708       msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_DEL, get_class()));
709     }
711     new log("remove","groups/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
713     /* Delete references to object groups */
714     $ldap->cd ($this->config->current['BASE']);
715     $ldap->search ("(&(objectClass=gosaGroupOfNames)(member=".LDAP::prepare4filter($this->dn)."))", array("cn"));
716     while ($ldap->fetch()){
717       $og= new ogroup($this->config, $ldap->getDN());
718       unset($og->member[$this->dn]);
719       $og->save ();
720     }
722     /* Remove ACL dependencies too,
723      */
724     $ldap = $this->config->get_ldap_link();
725     $ldap->cd($this->config->current['BASE']);
726     $ldap->search("(&(objectClass=gosaAcl)(gosaAclEntry=*".base64_encode($this->dn)."*))",array("gosaAclEntry","dn"));
727     while($attrs = $ldap->fetch()){
728       $acl = new acl($this->config,$this->parent,$attrs['dn']);
729       foreach($acl->gosaAclEntry as $id => $entry){
730         foreach($entry['members'] as $m_id => $member){
731           if($m_id == "G:".$this->dn || $m_id == "U:".$this->dn){
732             unset($acl->gosaAclEntry[$id]['members'][$m_id]);
733             gosa_log("modify","groups/acl",$attrs['dn'],array(),sprintf("Removed acl for %s on object %s.",$this->dn,$attrs['dn']));
734           }
735         }
736       }
737       $acl->save();
738     }
740     /* Remove ACL dependencies, too */
741     acl::remove_acl_for($this->dn);
743     /* Send signal to the world that we've done */
744     $this->handle_post_events("remove");
745   }
748   /* Save data to object */
749   function save_object()
750   {
751     /* Refresh base */
752     if ($this->acl_is_moveable($this->base)){
753       if (!$this->baseSelector->update()) {
754         msg_dialog::display(_("Error"), msgPool::permMove(), ERROR_DIALOG);
755       }
756       if ($this->base != $this->baseSelector->getBase()) {
757         $this->base= $this->baseSelector->getBase();
758         $this->is_modified= TRUE;
759       }
760     }
762     /* Save additional values for possible next step */
763     if (isset($_POST['groupedit'])){
765       /* Create a base backup and reset the 
766           base directly after calling plugin::save_object();  
767          Base will be set seperatly a few lines below */
768       $base_tmp = $this->base;
769       plugin::save_object();
770       $this->base = $base_tmp;
772       $this->force_gid= 0;
774       /* Only reset sambagroup flag if we are able to write this flag */
775       if($this->acl_is_writeable("sambaGroupType")){
776         $this->smbgroup = 0;
777       }
779       foreach (array(
780             "force_gid"  => "gidNumber", 
781             "smbgroup"   => "sambaGroupType") as $val => $aclname) {
782         if ($this->acl_is_writeable($aclname)  && isset($_POST["$val"])){
783           $this->$val= $_POST["$val"];
784         }
785       }
787       /* Save sambaDomain attribute */
788       if ($this->acl_is_writeable("sambaDomainName") && isset ($_POST['sambaDomainName'])){
789         $this->sambaDomainName= $_POST['sambaDomainName'];
790         $this->groupType= $_POST['groupType'];
791       }
793       /* Save fon attribute */
794       if ($this->acl_is_writeable("fonGroup")){
795         if (isset ($_POST['fon_group'])){
796           $this->fon_group= TRUE;
797         } else {
798           $this->fon_group= FALSE;
799         }
800       }
801       if ($this->acl_is_writeable("nagiosGroup")){
802         if (isset ($_POST['nagios_group'])){
803           $this->nagios_group= TRUE;
804         } else {
805           $this->nagios_group= FALSE;
806         }
807       }
808     }
810     /* Trust mode - special handling */
811     if($this->acl_is_writeable("trustModel")){
812       if (isset($_POST['trustmode'])){
813         $saved= $this->trustModel;
814         if ($_POST['trustmode'] == "1"){
815           $this->trustModel= "fullaccess";
816         } elseif ($_POST['trustmode'] == "2"){
817           $this->trustModel= "byhost";
818         } else {
819           $this->trustModel= "";
820         }
821         if ($this->trustModel != $saved){
822           $this->is_modified= TRUE;
823         }
824       }
825     }
827   }
830   /* Save to LDAP */
831   function save()
832   {
834     /* ID handling */
835     if ($this->force_gid == 0){
836       if ($this->saved_gidNumber != ""){
837         $this->gidNumber= $this->saved_gidNumber;
838       } else {
839         /* Calculate new, lock uids */
840         $wait= 10;
841         while (get_lock("gidnumber") != ""){
842           sleep (1);
844           /* timed out? */
845           if ($wait-- == 0){
846             break;
847           }
848         }
849         add_lock ("gidnumber", "gosa");
850         $this->gidNumber= get_next_id("gidNumber", $this->dn);
851       }
852     }
853   
854     plugin::save(); 
856  /* Trust accounts */
857     $objectclasses= array();
858     foreach ($this->attrs['objectClass'] as $key => $class){
859       if (preg_match('/trustAccount/i', $class)){
860         continue;
861       }
862       $objectclasses[]= $this->attrs['objectClass'][$key];
863     }
864     $this->attrs['objectClass']= $objectclasses;
865     if ($this->trustModel != ""){
866       $this->attrs['objectClass'][]= "trustAccount";
867       $this->attrs['trustModel']= $this->trustModel;
868       $this->attrs['accessTo']= array();
869       if ($this->trustModel == "byhost"){
870         foreach ($this->accessTo as $host){
871           $this->attrs['accessTo'][]= $host;
872         }
873       }
874     } else {
875       if ($this->was_trust_account){
876         $this->attrs['accessTo']= array();
877         $this->attrs['trustModel']= array();
878       }
879     }
883     /* Remove objectClass for samba/phone support */
884     $tmp= array();
885     for ($i= 0; $i<count($this->attrs["objectClass"]); $i++){
886       if ($this->attrs['objectClass'][$i] != 'sambaGroupMapping' &&
887           $this->attrs['objectClass'][$i] != 'sambaIdmapEntry' &&
888           $this->attrs['objectClass'][$i] != 'goFonPickupGroup' &&
889          $this->attrs['objectClass'][$i] != 'nagiosContactGroup'){
890         $tmp[]= $this->attrs['objectClass'][$i];
891       }
892     }
893     $this->attrs['objectClass']= $tmp;
894     $ldap= $this->config->get_ldap_link();
896     /* Add samba group functionality */
897     if ($this->smbgroup){
898   
899       /* Fixed undefined index ... 
900        */ 
901       $this->SID = $this->ridBase = "";
902       if(isset($this->config->data['SERVERS']['SAMBA'][$this->sambaDomainName]['SID'])){
903         $this->SID    = $this->config->data['SERVERS']['SAMBA'][$this->sambaDomainName]['SID'];
904       }else{
905         msg_dialog::display(_("Error"), sprintf(_("Cannot find any SID for '%s'!"), $this->sambaDomainName), ERROR_DIALOG);
906       }
907       if(isset($this->config->data['SERVERS']['SAMBA'][$this->sambaDomainName]['RIDBASE'])){
908         $this->ridBase= $this->config->data['SERVERS']['SAMBA'][$this->sambaDomainName]['RIDBASE']; 
909       }else{
910         msg_dialog::display(_("Error"), sprintf(_("Cannot find any RIDBASE for '%s'!"), $this->sambaDomainName), ERROR_DIALOG);
911       }
913       $this->attrs['objectClass'][]= 'sambaGroupMapping';
914       $this->attrs['sambaGroupType']= "2";
916       /* Check if we need to create a special entry */
917       if ($this->groupType == 0){
919         if ($this->sambaSID == "" || $this->oldgroupType != $this->groupType){
920           $gidNumber= $this->gidNumber;
921           while(TRUE){
922             $sid= $this->SID."-".($gidNumber*2 + $this->ridBase+1);
923             $ldap->cd($this->config->current['BASE']);
924             $ldap->search("(sambaSID=$sid)",array("sambaSID"));
925             if ($ldap->count() == 0){
926               break;
927             }
928             $gidNumber++;
929           }
930           $this->attrs['sambaSID']= $sid;
931           $this->sambaSID= $sid;
932         }
934       } else {
935         $this->attrs['sambaSID']=$this->SID."-".$this->groupType;
936       }
938       /* User wants me to fake the idMappings? This is useful for
939          making winbind resolve the group names in a reasonable amount
940          of time in combination with larger databases. */
941       if ($this->config->get_cfg_value("sambaidmapping") == "true"){
942         $this->attrs['objectClass'][]= "sambaIdmapEntry";
943       }
945     }
947     /* Add phone functionality */
948     if ($this->fon_group){
949       $this->attrs['objectClass'][]= "goFonPickupGroup";
950     }
952     /* Add nagios functionality */
953     if ($this->nagios_group){
954       $this->attrs['objectClass'][]= "nagiosContactGroup";
955     }
957     /* Take members array */
958     if (count ($this->memberUid)){
959       $this->attrs['memberUid']= array_values(array_unique($this->memberUid));
960     }
962     /* New accounts need proper 'dn', propagate it to remaining objects */
963     if ($this->dn == 'new'){
964       $this->dn= 'cn='.$this->cn.','.get_groups_ou().$this->base;
965     }
967     /* Add member dn's for RFC2307bis Support */
968     if ($this->rfc2307bis){
969       $this->attrs['member'] = array();
970       if (count($this->memberUid)){
971         foreach($this->attrs['memberUid'] as $uid) {
973           if(isset($this->dnMapping[$uid])){
974             $this->attrs['member'][]= $this->dnMapping[$uid];
975           }
976         }
977       } else {
978         $this->attrs['member'][]= $this->dn;
979       }
980     }
982     /* Save data. Using 'modify' implies that the entry is already present, use 'add' for
983        new entries. So do a check first... */
984     $ldap->cat ($this->dn, array('dn'));
985     if ($ldap->fetch()){
986       /* Modify needs array() to remove values :-( */
987       if (!count ($this->memberUid)){
988         $this->attrs['memberUid']= array();
989       }
990       if (!$this->smbgroup){
991         $this->attrs['sambaGroupType']= array();
992         $this->attrs['sambaSID']= array();
993       }
994       
995       $mode= "modify";
996     } else {
997       $mode= "add";
998       $ldap->cd($this->config->current['BASE']);
999       $ldap->create_missing_trees(preg_replace('/^[^,]+,/', '', $this->dn));
1000     }
1003     /* Check generated gidNumber, it may be used by another group. 
1004      */
1005     if($this->gidNumber != ""){
1006       $ldap->cd($this->config->current['BASE']);
1007       $ldap->search("(&(!(cn=".$this->orig_cn."))(objectClass=posixGroup)(gidNumber=".$this->gidNumber."))",array("cn"));
1008       if($ldap->count()){
1009         $cns = "";
1010         while($attrs = $ldap->fetch()){
1011           $cns .= $attrs['cn'][0].", ";
1012         }
1013         $cns = rtrim($cns,", ");
1014         msg_dialog::display(_("Warning"),sprintf(_("The gidNumber '%s' is already in use by %s!"),$this->gidNumber,$cns) , WARNING_DIALOG );
1015       }
1016     }
1018     /* Write back to ldap */
1019     $ldap->cd($this->dn);
1020     $this->cleanup();
1021     $ldap->$mode($this->attrs);
1023     /* Remove ACL dependencies too,
1024      */
1025     if($this->dn != $this->orig_dn && $this->orig_dn != "new"){
1026       $tmp = new acl($this->config,$this->parent,$this->dn);
1027       $tmp->update_acl_membership($this->orig_dn,$this->dn);
1028     }
1030     if($this->initially_was_account){
1031       new log("modify","groups/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
1032     }else{
1033       new log("create","groups/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
1034     }
1036     $ret= 0;
1037     if (!$ldap->success()){
1038       msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, 0, get_class()));
1039       $ret= 1;
1040     }
1042     /* Remove uid lock */
1043     del_lock ("gidnumber");
1045     /* Post that we've done*/
1046     $this->handle_post_events($mode);
1048     return ($ret);
1049   }
1051   function check()
1052   {
1053     /* Call common method to give check the hook */
1054     $message= plugin::check();
1056     /* Permissions for that base? */
1057     if ($this->base != ""){
1058       $new_dn= 'cn='.$this->cn.','.get_groups_ou().$this->base;
1059     } else {
1060       $new_dn= $this->dn;
1061     }
1063     /* must: cn */
1064     if ($this->cn == "" && $this->acl_is_writeable("cn")){
1065       $message[]= msgPool::required(_("Name"));
1066     }
1068     /* Check for valid input */
1069     if (!tests::is_uid($this->cn)){
1070       if (strict_uid_mode()){
1071         $message[]= msgPool::invalid(_("Name"), $this->cn, "/[a-z0-9_-]/");
1072       } else {
1073         $message[]= msgPool::invalid(_("Name"), $this->cn, "/[a-z0-9_-]/i");
1074       }
1075     }
1077     if($this->allowGroupsWithSameNameInOtherSubtrees == true){
1079       /* Check for used 'cn' */
1080       $ldap= $this->config->get_ldap_link();
1081       if(($this->cn  != $this->orig_cn) || ($this->orig_dn == "new")){
1082         $ldap->cd(get_groups_ou().$this->base);
1083         $ldap->ls("(&(|(objectClass=gosaGroupOfNames)(objectClass=posixGroup))(cn=$this->cn))",get_groups_ou().$this->base,array("cn"));
1084         if ($ldap->count() != 0){
1085           $message[]= msgPool::duplicated(_("Name"));
1086         }
1087       }
1089     }else{
1091       /* Check for used 'cn' */
1092       $ldap= $this->config->get_ldap_link();
1093       $ldap->cd($this->config->current['BASE']);
1094       $ldap->search("(&(|(objectClass=gosaGroupOfNames)(objectClass=posixGroup))(cn=$this->cn))",array("cn"));
1095       if ($ldap->count() != 0){
1097         /* New entry? */
1098         if ($this->dn == 'new'){
1099           $message[]= msgPool::duplicated(_("Name"));
1100         }
1102         /* Moved? */
1103         elseif ($new_dn != $this->orig_dn){
1104           $ldap->fetch();
1105           if ($ldap->getDN() != $this->orig_dn){
1106             $message[]= msgPool::duplicated(_("Name"));
1107           }
1108         }
1109       }
1110     }
1111      
1112     /* Check ID */
1113     if ($this->force_gid == "1"){
1114       if (!tests::is_id($this->gidNumber)){
1115         $message[]= msgPool::invalid(_("GID"), $this->gidNumber, "/[0-9]/");
1116       } else {
1117         if ($this->gidNumber < $this->config->get_cfg_value("minId")){
1118           $message[]= msgPool::toosmall(_("GID"), $this->config->get_cfg_value("minId"));
1119         }
1121       }
1122     }
1123     
1124     /* Check if we are allowed to create or move this object 
1125      */
1126     if(!$this->orig_dn == "new" || 
1127         $this->orig_base != $this->base || 
1128         $this->cn != $this->orig_cn){
1130       if($this->orig_dn == "new" && !$this->acl_is_createable($this->base)){
1131         $message[] = msgPool::permCreate();
1132       }elseif($this->orig_dn != "new" && !$this->acl_is_moveable($this->base)){
1133         $message[] = msgPool::permMove();
1134       }
1135     }
1137     return ($message);
1138   }
1141   function getCopyDialog()
1142   {
1143     $vars = array("cn");
1144   
1145     if($this ->force_gid){
1146       $used = " checked ";
1147       $dis  = "";
1148     }else{
1149       $used = "";
1150       $dis  = " disabled ";
1151     }
1153     $smarty = get_smarty();
1154     $smarty->assign("used",$used);
1155     $smarty->assign("dis" ,$dis);
1156     $smarty->assign("cn" ,$this->cn);
1157     $smarty->assign("gidNumber",$this->gidNumber);
1158     $str = $smarty->fetch(get_template_path("paste_generic.tpl",TRUE));
1159     $ret = array();
1160     $ret['string'] = $str;
1161     $ret['status'] = "";
1162     return($ret);
1163   }
1165   function saveCopyDialog()
1166   {
1167     if(isset($_POST['cn'])){
1168       $this->cn = $_POST['cn'];
1169     }
1170     if(isset($_POST['force_gid'])){
1171       $this->force_gid  = 1;
1172       $this->gidNumber= $_POST['gidNumber'];
1173     }else{
1174       $this->force_gid  = 0;
1175       $this->gidNumber  = false;
1176     }
1177   }
1179   
1180   /* Return plugin informations for acl handling  */ 
1181   static function plInfo()
1182   {
1183     return (array(  
1184           "plShortName" => _("Generic"),
1185           "plDescription" => _("Generic group settings"),
1186           "plSelfModify"  => FALSE,
1187           "plDepends"     => array(),
1188           "plPriority"    => 0,
1189           "plSection"     => array("administration"),
1190           "plCategory"    => array("groups" => array("objectClass" => "posixGroup", "description" => _("Groups"))),
1192           "plProvidedAcls"    => array(
1193             "cn"                => _("Name"),
1194             "description"       => _("Description"),
1195             "base"              => _("Base"),
1197             "gidNumber"         => _("GID"),
1199             "sambaGroupType"    => _("Samba group type"),
1200             "sambaDomainName"   => _("Samba domain name"),
1201             "trustModel"        => _("System trust"),
1202             "fonGroup"          => _("Phone pickup group"),
1203             "nagiosGroup"       => _("Nagios group"),
1205             "memberUid"         => _("Group member"))
1206         ));
1207   }
1210   function multiple_save_object()
1211   {
1212     if(isset($_POST['group_mulitple_edit'])){
1214       /* Create a base backup and reset the
1215          base directly after calling plugin::save_object();
1216          Base will be set seperatly a few lines below */
1217       $base_tmp = $this->base;
1218       plugin::multiple_save_object();
1219       plugin::save_object();
1220       $this->base = $base_tmp;
1222       foreach(array("base","smbgroup","groupType","sambaDomainName","fon_group","nagios_group","trustmode") as $attr){
1223         if(isset($_POST['use_'.$attr])){
1224           $this->multi_boxes[] = $attr;
1225         }
1226       }
1228       /* Refresh base */
1229       if ($this->acl_is_moveable($this->base)){
1230         if (!$this->baseSelector->update()) {
1231           msg_dialog::display(_("Error"), msgPool::permMove(), ERROR_DIALOG);
1232         }
1233         if ($this->base != $this->baseSelector->getBase()) {
1234           $this->base= $this->baseSelector->getBase();
1235           $this->is_modified= TRUE;
1236         }
1237       }
1239       foreach (array( "smbgroup"   => "sambaGroupType" ,"nagios_group" => "nagios_group") as $val => $aclname) {
1240         if ($this->acl_is_writeable($aclname)){
1241           if(isset($_POST["$val"])){
1242             $this->$val=  TRUE;
1243           }else{
1244             $this->$val=  FALSE;
1245           }
1246         }
1247       }
1249       /* Save sambaDomain attribute */
1250       if ($this->acl_is_writeable("sambaDomainName") && isset ($_POST['sambaDomainName'])){
1251         $this->sambaDomainName= $_POST['sambaDomainName'];
1252         $this->groupType= $_POST['groupType'];
1253       }
1255       /* Trust mode - special handling */
1256       if($this->acl_is_writeable("trustModel")){
1257         if (isset($_POST['trustmode'])){
1258           $saved= $this->trustModel;
1259           if ($_POST['trustmode'] == "1"){
1260             $this->trustModel= "fullaccess";
1261           } elseif ($_POST['trustmode'] == "2"){
1262             $this->trustModel= "byhost";
1263           } else {
1264             $this->trustModel= "";
1265           }
1266           if ($this->trustModel != $saved){
1267             $this->is_modified= TRUE;
1268           }
1269         }
1270       }
1272       /* Save fon attribute */
1273       if ($this->acl_is_writeable("fonGroup")){
1274         if (isset ($_POST['fon_group'])){
1275           $this->fon_group= TRUE;
1276         } else {
1277           $this->fon_group= FALSE;
1278         }
1279       }
1280     }
1281   }
1284   function get_multi_edit_values()
1285   {
1286     $ret = plugin::get_multi_edit_values();
1288     foreach(array("base","smbgroup","groupType","sambaDomainName","fon_group","nagios_group") as $attr){    
1289       if(in_array($attr,$this->multi_boxes)){
1290         $ret[$attr] = $this->$attr;
1291       }
1292     }
1294     if(in_array("trustmode",$this->multi_boxes)){
1295       $ret['trustModel'] = $this->trustModel;
1296       $ret['accessTo'] = $this->accessTo;
1297     }
1299     $ret['memberUid'] = $this->memberUid;
1300     $ret['memberUid_used_by_some'] = $this->memberUid_used_by_some;
1301     return($ret);
1302   }
1304   function multiple_execute()
1305   {
1306     return($this->execute());
1307   }
1310   /* Initialize plugin with given atribute arrays
1311    */
1312   function init_multiple_support($attrs,$all)
1313   {
1314     plugin::init_multiple_support($attrs,$all);
1316     $this->memberUid = array();
1317     $this->memberUid_used_by_some = array();
1318     if (isset($attrs['memberUid'])){
1319       for ($i= 0; $i<$attrs['memberUid']['count']; $i++){
1320         $this->memberUid[$attrs['memberUid'][$i]]= $attrs['memberUid'][$i];
1321       }
1322       ksort($this->memberUid);
1323     }
1325     if (isset($all['memberUid'])){
1326       for ($i= 0; $i<$all['memberUid']['count']; $i++){
1327         if(!in_array($all['memberUid'][$i],$this->memberUid)){
1328           $this->memberUid_used_by_some[$all['memberUid'][$i]]= $all['memberUid'][$i];
1329         }
1330       }
1331       ksort($this->memberUid_used_by_some);
1332     }
1333   }
1336   function PrepareForCopyPaste($source)
1337   {
1338     plugin::PrepareForCopyPaste($source);
1340     $this->memberUid = array();
1341     if(isset($source['memberUid'])){
1342       for($i = 0 ; $i < $source['memberUid']['count']; $i ++){
1343         $this->memberUid[] = $source['memberUid'][$i];
1344       }
1345     }
1346     $this->accessTo = array();
1347     if (isset($source['accessTo'])){
1348       for ($i= 0; $i<$source['accessTo']['count']; $i++){
1349         $tmp= $source['accessTo'][$i];
1350         $this->accessTo[$tmp]= $tmp;
1351       }
1352     }
1353   }
1356   function set_multi_edit_values($attrs)
1357   {
1358     $users = array();
1360     /* Update groupMembership, keep optinal group */
1361     foreach($attrs['memberUid_used_by_some'] as $uid){
1362       if(in_array($uid,$this->memberUid)){
1363         $users[$uid] = $uid;
1364       }
1365     }
1367     /* Update groupMembership, add forced groups */
1368     foreach($attrs['memberUid'] as $uid){
1369       $users[$uid] = $uid;
1370     }
1371     plugin::set_multi_edit_values($attrs);
1372     $this->memberUid = $users;
1373   }
1375 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1376 ?>