Code

Fixed saving of trust mode settings for groups
[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   /* attribute list for save action */
64   var $attributes= array("cn", "description", "gidNumber","memberUid","sambaGroupType","sambaSID");
65   var $objectclasses= array("top", "posixGroup");
67   var $CopyPasteVars  = array("force_gid","fon_group","smbgroup","groupType","sambaSID","sambaDomainName","SID","nagios_group","sambaGroupType");
69   var $multiple_support = TRUE;
72     // Lists 
73     private $memberList;    // Single group editing
74     private $commonList;    // (Multiple support active)
75     private $partialList;   // (Multiple support active)
78   function group (&$config, $dn= NULL)
79   {
80      /* Set rfc2307bis flag */
81      if ($config->get_cfg_value("rfc2307bis") == "true"){
82        $this->rfc2307bis= TRUE;
83        $this->attributes[]= "member";
84        $this->objectclasses[]= "groupOfNames";
85      }
87     plugin::plugin ($config, $dn);
89     $this->trustModeDialog = new trustModeDialog($this->config, $this->dn,NULL);
90     $this->trustModeDialog->setAcl('groups/group');
92     /* Load attributes depending on the samba version */
93     $this->orig_dn= $dn;
94     $this->orig_cn= $this->cn;
96     /* Get member list */
97     if (isset($this->attrs['memberUid'][0])){
98       $tmp= array();
99       for ($i= 0; $i<$this->attrs['memberUid']['count']; $i++){
100         $tmp[$this->attrs['memberUid'][$i]]= $this->attrs['memberUid'][$i];
101       }
102       $this->memberUid= $tmp;
103       ksort ($this->memberUid);
104     }
106     /* Save gidNumber for later use */
107     if (isset($this->attrs['gidNumber'])){
108       $this->saved_gidNumber= $this->attrs['gidNumber'][0];
109     }
111     /* Is a samba group? */
112     if (isset($this->attrs['objectClass'])){
113       if (array_search ('sambaGroupMapping', $this->attrs['objectClass']) == FALSE ){
114         $this->smbgroup= FALSE;
115       } else {
116         $this->smbgroup= TRUE;
117         if (isset($this->attrs['sambaSID'])){
118           $this->sambaSID= $this->attrs['sambaSID'][0];
119         }
120       }
121       if (array_search ('goFonPickupGroup', $this->attrs['objectClass']) == FALSE ){
122         $this->fon_group= FALSE;
123       } else {
124         $this->fon_group= TRUE;
125       }
126       if (array_search ('nagiosContactGroup', $this->attrs['objectClass']) == FALSE ){
127         $this->nagios_group= FALSE;
128       } else {
129         $this->nagios_group= TRUE;
130       }
131     }
133     /* Set mail flag */
134     if (isset($this->attrs['objectClass']) && in_array('gosaMailAccount', $this->attrs['objectClass'])){
135       $this->has_mailAccount= TRUE;
136     }
138     /* Get samba Domain in case of samba 3 */
139     if ($this->sambaSID != ""){
140       $this->SID= preg_replace ("/-[^-]+$/", "", $this->sambaSID);
141       $ldap= $this->config->get_ldap_link();
142       $ldap->cd($this->config->current['BASE']);
143       $ldap->search ("(&(objectClass=sambaDomain)(sambaSID=$this->SID))",array("sambaAlgorithmicRidBase"));
144       if ($ldap->count() != 0){
145         $attrs= $ldap->fetch();
146         if(isset($attrs['sambaAlgorithmicRidBase'])){  
147           $this->ridBase= $attrs['sambaAlgorithmicRidBase'][0];  
148         } else {  
149           $this->ridBase= $this->config->get_cfg_value("sambaRidBase");
150         } 
152         /* Get domain name for SID */
153         $this->sambaDomainName= "DEFAULT";
154         foreach ($this->config->data['SERVERS']['SAMBA'] as $key => $val){
155           if ($val['SID'] == $this->SID){
156             $this->sambaDomainName= $key;
157             break;
158           }
159         }
160       } else {
161         if ($this->config->get_cfg_value("sambaRidBase") != ""){
162           $this->sambaDomainName= "DEFAULT";
163           $this->ridBase= $this->config->get_cfg_value("sambaRidBase");
164           $this->SID= $this->config->get_cfg_value("sid");
165         } else {
166           msg_dialog::display(_("Configuration error"), _("Cannot find group SID in your configuration!"), ERROR_DIALOG);
167         }
168       }
170       /* Get group type */
171       $this->groupType= (int)substr(strrchr($this->sambaSID, "-"), 1);
172       if ($this->groupType < 500 || $this->groupType > 553){
173         $this->groupType= 0;
174       }
175       $this->oldgroupType= $this->groupType;
176     }
178     if ($this->dn == "new"){
179       if(session::is_set('CurrentMainBase')){
180         $this->base = session::get('CurrentMainBase');
181       }else{
182         $ui= get_userinfo();
183         $this->base= dn2base($ui->dn);
184       }
185     } else {
187       /* Get object base */
188       $this->base =preg_replace ("/^[^,]+,".preg_quote(get_groups_ou(), '/')."/i","",$this->dn);
189     }
190     $this->orig_base = $this->base;
192     /* This is always an account */
193     $this->is_account= TRUE;
195     /* Instanciate base selector */
196     $this->baseSelector= new baseSelector($this->get_allowed_bases(), $this->base);
197     $this->baseSelector->setSubmitButton(false);
198     $this->baseSelector->setHeight(300);
199     $this->baseSelector->update(true);
203     // Prepare lists
204     $this->memberList = new sortableListing();
205     $this->memberList->setDeleteable(true);
206     $this->memberList->setInstantDelete(true);
207     $this->memberList->setEditable(false);
208     $this->memberList->setWidth("100%");
209     $this->memberList->setHeight("300px");
210     $this->memberList->setHeader(array('~',_("Given name"),_("Surename"),_("Uid")));
211     $this->memberList->setColspecs(array('20px','*','*','*','20px'));
212     $this->memberList->setDefaultSortColumn(1);
214     $this->reload(TRUE);
215   }
217   function execute()
218   {
219     /* Call parent execute */
220     plugin::execute();
222     /* Log view */
223     if($this->is_account && !$this->view_logged){
224       $this->view_logged = TRUE;
225       new log("view","groups/".get_class($this),$this->dn);
226     }
228     /* Do we represent a valid group? */
229     if (!$this->is_account && $this->parent === NULL){
230       $display= "<img alt=\"\" src=\"images/small-error.png\" align=\"middle\">&nbsp;<b>".msgPool::noValidExtension()."</b>";
231       return ($display);
232     }
234     // Act on list events 
235     foreach(array('memberList','commonList','partialList') as $list){
237         // Check if list is available, depends on multi- or sinlge- group editing. 
238         if($this->$list){
239             $this->$list->save_object();
240             $action = $this->$list->getAction();
241             if($action['action'] == 'delete' && preg_match("/w/",$this->getacl("memberUid"))){
242                 foreach ($action['targets'] as $id){
243                     $value = $this->$list->getKey($id);
244                     unset ($this->members["$value"]);
245                     $this->removeUser($value);
246                 }
247                 $this->reload();
248             }
249         }
250     }
252     /* Add objects? */
253     if (isset($_POST["edit_membership"]) && preg_match("/w/",$this->getacl("memberUid"))){
254       $this->userSelect= new userSelect($this->config, get_userinfo());
255     }
257     /* Add objects finished? */
258     if (isset($_POST["add_users_cancel"])){
259       $this->userSelect= NULL;
260     }
262     /* Add user to group */
263     if (isset($_POST['add_users_finish']) && $this->userSelect){
264   
265       $users = $this->userSelect->detectPostActions();
266       if(isset($users['targets'])){
267         $headpage = $this->userSelect->getHeadpage();
268         foreach($users['targets'] as $dn){
269           $attrs = $headpage->getEntry($dn);
270           $value = $attrs['uid'][0];
271           $this->addUser($value);
272           $this->members["$value"]= $this->allusers[$value];
273           $this->reload();
274         }
275       }
276       $this->userSelect= NULL;
277     }
279     $smarty= get_smarty();
280  
281     // Handle trust mode dialog
282     $this->dialog = FALSE;
283     $trustModeDialog = $this->trustModeDialog->execute();
284     if($this->trustModeDialog->trustSelect){
285         $this->dialog = TRUE;
286         return($trustModeDialog);
287     }
288     $smarty->assign("trustModeDialog" , $trustModeDialog);
290     $smarty->assign("usePrototype", "true");
292     if($this->config->search("nagiosaccount", "CLASS",array('menu'))){
293       $smarty->assign("nagios",true);
294     }else{
295       $smarty->assign("nagios",false);
296     }
297     
298     if($this->config->search("phoneAccount", "CLASS",array('menu'))){
299       $smarty->assign("pickupGroup",true);
300     }else{
301       $smarty->assign("pickupGroup",false);
302     }
304     /* Manage object add dialog */
305     if ($this->userSelect){
306       $this->dialog = TRUE;
307       return($this->userSelect->execute());
308     }
310     /* Create base acls */
311     $smarty->assign("base", $this->baseSelector->render());
313     $domains= array();
314     foreach($this->config->data['SERVERS']['SAMBA'] as $name => $content){
315       $domains[$name]= $name;
316     }
317     $smarty->assign("sambaDomains", $domains);
318     $smarty->assign("sambaDomainName", $this->sambaDomainName);
319     $groupTypes= array(0 => _("Samba group"), 512 => _("Domain admins"), 513 => _("Domain users"),
320         514 => _("Domain guests"));
322     /* Don't loose special groups! If not key'ed above, add it to
323        the combo box... */      
324     if ($this->groupType >= 500 && $this->groupType <= 553 && !isset($groupTypes[$this->groupType])){
325       $groupTypes[$this->groupType]= sprintf(_("Special group (%d)"), $this->groupType);
326     }
328     $smarty->assign("groupTypes", $groupTypes);
329     $smarty->assign("groupType", $this->groupType);
330     
332     /* Members and users */
333     if(!$this->multiple_support_active){
334         $this->memberList->setAcl($this->getacl("memberUid"));
335         $data = $lData = array();
336         foreach($this->members as $uid => $member){
337             $data[$uid] = $member;
338             $givenName = $sn = _("Unknown");
339             if(isset($member['sn'][0])) $sn = $member['sn'][0];
340             if(isset($member['givenName'][0])) $givenName = $member['givenName'][0];
341             $image = image('images/false.png');
342             if(isset($member['sn'])){
343                 $image = image('plugins/users/images/select_user.png');
344             }
345             $lData[$uid] = array('data' => array($image,$sn, $givenName, $uid));
346         }
347         $this->memberList->setListData($data,$lData);
348         $this->memberList->update();
349         $smarty->assign("memberList", $this->memberList->render());
350     }else{
351     
352         $this->commonList->setAcl($this->getacl("memberUid"));
353         $this->partialList->setAcl($this->getacl("memberUid"));
355         $data = $lData = array();
356         foreach($this->memberUid as $uid => $member){
357             $member = $this->members[$member];
358             $data[$uid] = $member;
359             $givenName = $sn = _("Unknown");
360             if(isset($member['sn'][0])) $sn = $member['sn'][0];
361             if(isset($member['givenName'][0])) $givenName = $member['givenName'][0];
362             $image = image('images/false.png');
363             if(isset($member['sn'])){
364                 $image = image('plugins/users/images/select_user.png');
365             }
366             $lData[$uid] = array('data' => array($image,$sn, $givenName, $uid));
367         }
368         $this->commonList->setListData($data,$lData);
369         $this->commonList->update();
370         $smarty->assign("commonList", $this->commonList->render());
372         $data = $lData = array();
373         foreach($this->memberUid_used_by_some as $uid => $member){
374             $member = $this->members[$member];
375             $data[$uid] = $member;
376             $givenName = $sn = _("Unknown");
377             if(isset($member['sn'][0])) $sn = $member['sn'][0];
378             if(isset($member['givenName'][0])) $givenName = $member['givenName'][0];
379             $image = image('images/false.png');
380             if(isset($member['sn'])){
381                 $image = image('plugins/users/images/select_user.png');
382             }
383             $lData[$uid] = array('data' => array($image,$sn, $givenName, $uid));
384         }
385         $this->partialList->setListData($data,$lData);
386         $this->partialList->update();
387         $smarty->assign("partialList", $this->partialList->render());
388     }
390     /* Checkboxes */
391     foreach (array("force_gid", "smbgroup") as $val){
392       if ($this->$val == "1"){
393         $smarty->assign("$val", "checked");
394       } else {
395         $smarty->assign("$val", "");
396       }
397     }
398     if ($this->force_gid != "1"){
399       $smarty->assign("forceMode", "disabled");
400     }else{
401       $smarty->assign("forceMode", "");
402     }
403     if ($this->fon_group){
404       $smarty->assign("fon_group", "checked");
405     } else {
406       $smarty->assign("fon_group", "");
407     }
409     if ($this->nagios_group){
410       $smarty->assign("nagios_group", "checked");
411     } else {
412       $smarty->assign("nagios_group", "");
413     }
415     /* Fields */
416     foreach (array("cn", "description", "gidNumber") as $val){
417       $smarty->assign("$val", $this->$val);
418     }
420     $tmp = $this->plInfo();
421     foreach($tmp['plProvidedAcls'] as $name => $translation){
422       $smarty->assign($name."ACL",$this->getacl($name));
423     }
424     
425     if($this->acl_is_writeable("base")){
426       $smarty->assign("baseSelect",true);
427     }else{
428       $smarty->assign("baseSelect",false);
429     }
431     /* Multiple edit handling */
432     $smarty->assign("multiple_support",$this->multiple_support_active);
434     foreach($this->attributes as $val){
435       if(in_array($val,$this->multi_boxes)){
436         $smarty->assign("use_".$val,TRUE);
437       }else{
438         $smarty->assign("use_".$val,FALSE);
439       }
440     }
441     foreach(array("base","smbgroup","groupType","sambaDomainName","fon_group","nagios_group") as $val){
442       if(in_array($val,$this->multi_boxes)){
443         $smarty->assign("use_".$val,TRUE);
444       }else{
445         $smarty->assign("use_".$val,FALSE);
446       }
447     }
449     return($smarty->fetch (get_template_path('generic.tpl', TRUE)));
450   }
452   function addUser($uid)
453   {
454     /* In mutliple edit we have to handle two arrays.
455      *  memberUid               : Containing users used in all groups
456      *  memberUid_used_by_some  : Those which are not used in all groups
457      * So we have to remove the given $uid from the ..used_by_some array first.
458      */
459     if($this->multiple_support_active){
460       if(isset($this->memberUid_used_by_some[$uid])){
461         unset($this->memberUid_used_by_some[$uid]);
462       }
463     }  
465     /* Ensure that the requested object is known to the group class 
466      */
467     if(!isset($this->dnMapping[$uid])){
468       $ldap = $this->config->get_ldap_link();
469       $ldap->cd($this->config->current['BASE']);
470       $ldap->search("(&(objectClass=gosaAccount)(uid=".$uid."))",array("dn", "uid","sn","givenName"));
471       if($ldap->count() == 0 ){
472         msg_dialog::display(_("Error"), 
473             sprintf(_("Adding UID '%s' to group '%s' failed: cannot find user object!"), 
474               $uid,$this->cn), 
475             ERROR_DIALOG);
476         return;
477       }elseif($ldap->count() >= 2){
478         msg_dialog::display(_("Error"), 
479             sprintf(_("Add UID '%s' to group '%s' failed: UID is used more than once!"),
480               $uid,$this->cn), 
481             ERROR_DIALOG);
482         return;
483       }else{
484         while($attrs = $ldap->fetch()){
485           $this->dnMapping[$attrs['uid'][0]] = $attrs['dn'];
486           $this->members[$attrs['uid'][0]] = $attrs;
487           $this->allusers[$attrs['uid'][0]]= $attrs;
488         }
489       }
490     }
492     $this->memberUid[$uid]= $uid;
493   }
496   function removeUser($uid)
497   {
498     $temp= array();
499     if(isset($this->memberUid[$uid])){
500       unset($this->memberUid[$uid]);
501     }
503     /* We have two array contianing group members in multiple edit.
504      *  this->memberUid             : Groups used by all currently edited groups 
505      *  this->memberUid_used_by_some: Used by some 
506      * So we have to remove the specified uid from both arrays.
507      */
508     if($this->multiple_support_active){
509       if(isset($this->memberUid_used_by_some[$uid])){
510         unset($this->memberUid_used_by_some[$uid]);
511       }
512     }
513   }
515   /* Reload data */
516   function reload($silent = FALSE)
517   {
518     /* Prepare ldap link */
519     $ldap= $this->config->get_ldap_link();
520     $ldap->cd($this->config->current['BASE']);
523     /* Resolve still unresolved memberuids to fill the list with sn/giveName attributes 
524         (Store gathered sn/givenName informations in $this->allusers too, 
525          to be prepared when adding/deleting users)
526      */    
527     $filter = "";
529     // Merge in partial uids in multiple edit
530     $uids = array_keys($this->memberUid);
531     if($this->multiple_support_active) {
532         $uids = array_merge($uids,  array_keys($this->memberUid_used_by_some));
533     }
534     
535     if ($this->config->get_cfg_value("ldapFilterNestingLimit") == "" ||
536         count($uids) < $this->config->get_cfg_value("ldapFilterNestingLimit")){
537       foreach ($uids as $value){
538         if(!isset($this->members[$value])){
539           $filter .= "(uid=".normalizeLdap($value).")";
540         }
541       }
542     }
544     if(!empty($filter)){    
545       $ldap->cd($this->config->current['BASE']);
546       $ldap->search("(&(objectClass=gosaAccount)(|".$filter."))",array("dn", "uid","sn","givenName"));
547       while($attrs = $ldap->fetch()){
548         $this->dnMapping[$attrs['uid'][0]] = $attrs['dn'];
549         $this->members[$attrs['uid'][0]] = $attrs;
550         $this->allusers[$attrs['uid'][0]]= $attrs;
551       } 
552     }
553   
554     /* check if all uids are resolved */
555     if ($this->config->get_cfg_value("ldapFilterNestingLimit") == "" ||
556         count($this->memberUid) < $this->config->get_cfg_value("ldapFilterNestingLimit")){
557       foreach ($this->memberUid as $value){
558         if(!isset($this->members[$value])){
559           $this->members[$value] = "";
560         }
561       }  
562     }else{
563       foreach ($this->memberUid as $value){
564         $this->members[$value] = "";
565       }  
566     }
567   }
570   /* Create display name, this was used so often that it is excluded into a seperate function */
571   function createResultName($attrs)
572   {
573     if (isset($attrs["givenName"][0]) && isset($attrs["sn"][0])){
574       $ret =  $attrs["sn"][0].", ".$attrs["givenName"][0]." [".$attrs["uid"][0]."]";
575     } else {
576       $ret= $attrs['uid'][0];
577     }
578     return($ret);
579   }
582   function remove_from_parent()
583   {
584     plugin::remove_from_parent();
586     $ldap= $this->config->get_ldap_link();
587     $ldap->rmdir($this->dn);
588     if (!$ldap->success()){
589       msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_DEL, get_class()));
590     }
592     new log("remove","groups/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
594     /* Delete references to object groups */
595     $ldap->cd ($this->config->current['BASE']);
596     $ldap->search ("(&(objectClass=gosaGroupOfNames)(member=".LDAP::prepare4filter($this->dn)."))", array("cn"));
597     while ($ldap->fetch()){
598       $og= new ogroup($this->config, $ldap->getDN());
599       unset($og->member[$this->dn]);
600       $og->save ();
601     }
603     /* Remove ACL dependencies too,
604      */
605     $ldap = $this->config->get_ldap_link();
606     $ldap->cd($this->config->current['BASE']);
607     $ldap->search("(&(objectClass=gosaAcl)(gosaAclEntry=*".base64_encode($this->dn)."*))",array("gosaAclEntry","dn"));
608     while($attrs = $ldap->fetch()){
609       $acl = new acl($this->config,$this->parent,$attrs['dn']);
610       foreach($acl->gosaAclEntry as $id => $entry){
611         foreach($entry['members'] as $m_id => $member){
612           if($m_id == "G:".$this->dn || $m_id == "U:".$this->dn){
613             unset($acl->gosaAclEntry[$id]['members'][$m_id]);
614             gosa_log("modify","groups/acl",$attrs['dn'],array(),sprintf("Removed acl for %s on object %s.",$this->dn,$attrs['dn']));
615           }
616         }
617       }
618       $acl->save();
619     }
621     /* Remove ACL dependencies, too */
622     acl::remove_acl_for($this->dn);
624     /* Send signal to the world that we've done */
625     $this->handle_post_events("remove");
626   }
629   /* Save data to object */
630   function save_object()
631   {
632     /* Save additional values for possible next step */
633     if (isset($_POST['groupedit'])){
635       /* Create a base backup and reset the 
636           base directly after calling plugin::save_object();  
637          Base will be set seperatly a few lines below */
638       $base_tmp = $this->base;
639       plugin::save_object();
640       $this->trustModeDialog->save_object();
641       $this->base = $base_tmp;
643       /* Refresh base */
644       if ($this->acl_is_moveable($this->base)){
645         if (!$this->baseSelector->update()) {
646           msg_dialog::display(_("Error"), msgPool::permMove(), ERROR_DIALOG);
647         }
648         if ($this->base != $this->baseSelector->getBase()) {
649           $this->base= $this->baseSelector->getBase();
650           $this->is_modified= TRUE;
651         }
652       }
654       $this->force_gid= 0;
656       /* Only reset sambagroup flag if we are able to write this flag */
657       if($this->acl_is_writeable("sambaGroupType")){
658         $this->smbgroup = 0;
659       }
661       foreach (array(
662             "force_gid"  => "gidNumber", 
663             "smbgroup"   => "sambaGroupType") as $val => $aclname) {
664         if ($this->acl_is_writeable($aclname)  && isset($_POST["$val"])){
665           $this->$val= $_POST["$val"];
666         }
667       }
669       /* Save sambaDomain attribute */
670       if ($this->acl_is_writeable("sambaDomainName") && isset ($_POST['sambaDomainName'])){
671         $this->sambaDomainName= $_POST['sambaDomainName'];
672         $this->groupType= $_POST['groupType'];
673       }
675       /* Save fon attribute */
676       if ($this->acl_is_writeable("fonGroup")){
677         if (isset ($_POST['fon_group'])){
678           $this->fon_group= TRUE;
679         } else {
680           $this->fon_group= FALSE;
681         }
682       }
683       if ($this->acl_is_writeable("nagiosGroup")){
684         if (isset ($_POST['nagios_group'])){
685           $this->nagios_group= TRUE;
686         } else {
687           $this->nagios_group= FALSE;
688         }
689       }
690     }
691   }
694   /* Save to LDAP */
695   function save()
696   {
698     /* ID handling */
699     if ($this->force_gid == 0){
700       if ($this->saved_gidNumber != ""){
701         $this->gidNumber= $this->saved_gidNumber;
702       } else {
703         /* Calculate new, lock uids */
704         $wait= 10;
705         while (get_lock("gidnumber") != ""){
706           sleep (1);
708           /* timed out? */
709           if ($wait-- == 0){
710             break;
711           }
712         }
713         add_lock ("gidnumber", "gosa");
714         $this->gidNumber= get_next_id("gidNumber", $this->dn);
715       }
716     }
717   
718     plugin::save(); 
720     /* Remove objectClass for samba/phone support */
721     $tmp= array();
722     for ($i= 0; $i<count($this->attrs["objectClass"]); $i++){
723       if ($this->attrs['objectClass'][$i] != 'sambaGroupMapping' &&
724           $this->attrs['objectClass'][$i] != 'sambaIdmapEntry' &&
725           $this->attrs['objectClass'][$i] != 'goFonPickupGroup' &&
726          $this->attrs['objectClass'][$i] != 'nagiosContactGroup'){
727         $tmp[]= $this->attrs['objectClass'][$i];
728       }
729     }
730     $this->attrs['objectClass']= $tmp;
731     $ldap= $this->config->get_ldap_link();
733     /* Add samba group functionality */
734     if ($this->smbgroup){
735   
736       /* Fixed undefined index ... 
737        */ 
738       $this->SID = $this->ridBase = "";
739       if(isset($this->config->data['SERVERS']['SAMBA'][$this->sambaDomainName]['SID'])){
740         $this->SID    = $this->config->data['SERVERS']['SAMBA'][$this->sambaDomainName]['SID'];
741       }else{
742         msg_dialog::display(_("Error"), sprintf(_("Cannot find any SID for '%s'!"), $this->sambaDomainName), ERROR_DIALOG);
743       }
744       if(isset($this->config->data['SERVERS']['SAMBA'][$this->sambaDomainName]['RIDBASE'])){
745         $this->ridBase= $this->config->data['SERVERS']['SAMBA'][$this->sambaDomainName]['RIDBASE']; 
746       }else{
747         msg_dialog::display(_("Error"), sprintf(_("Cannot find any RIDBASE for '%s'!"), $this->sambaDomainName), ERROR_DIALOG);
748       }
750       $this->attrs['objectClass'][]= 'sambaGroupMapping';
751       $this->attrs['sambaGroupType']= "2";
753       /* Check if we need to create a special entry */
754       if ($this->groupType == 0){
756         if ($this->sambaSID == "" || $this->oldgroupType != $this->groupType){
757           $sid = $this->getSambaSID();
758           $this->attrs['sambaSID']= $sid;
759           $this->sambaSID= $sid;
760         }
762       } else {
763         $this->attrs['sambaSID']=$this->SID."-".$this->groupType;
764       }
766       /* User wants me to fake the idMappings? This is useful for
767          making winbind resolve the group names in a reasonable amount
768          of time in combination with larger databases. */
769       if ($this->config->get_cfg_value("sambaidmapping") == "true"){
770         $this->attrs['objectClass'][]= "sambaIdmapEntry";
771       }
773     }
775     /* Add phone functionality */
776     if ($this->fon_group){
777       $this->attrs['objectClass'][]= "goFonPickupGroup";
778     }
780     /* Add nagios functionality */
781     if ($this->nagios_group){
782       $this->attrs['objectClass'][]= "nagiosContactGroup";
783     }
785     /* Take members array */
786     if (count ($this->memberUid)){
787       $this->attrs['memberUid']= array_values(array_unique($this->memberUid));
788     }
790     /* New accounts need proper 'dn', propagate it to remaining objects */
791     if ($this->dn == 'new'){
792       $this->dn= 'cn='.$this->cn.','.get_groups_ou().$this->base;
793     }
795     /* Add member dn's for RFC2307bis Support */
796     if ($this->rfc2307bis){
797       $this->attrs['member'] = array();
798       if (count($this->memberUid)){
799         foreach($this->attrs['memberUid'] as $uid) {
801           if(isset($this->dnMapping[$uid])){
802             $this->attrs['member'][]= $this->dnMapping[$uid];
803           }
804         }
805       } else {
806         $this->attrs['member'][]= $this->dn;
807       }
808     }
810     /* Save data. Using 'modify' implies that the entry is already present, use 'add' for
811        new entries. So do a check first... */
812     $ldap->cat ($this->dn, array('dn'));
813     if ($ldap->fetch()){
814       /* Modify needs array() to remove values :-( */
815       if (!count ($this->memberUid)){
816         $this->attrs['memberUid']= array();
817       }
818       if (!$this->smbgroup){
819         $this->attrs['sambaGroupType']= array();
820         $this->attrs['sambaSID']= array();
821       }
822       
823       $mode= "modify";
824     } else {
825       $mode= "add";
826       $ldap->cd($this->config->current['BASE']);
827       $ldap->create_missing_trees(preg_replace('/^[^,]+,/', '', $this->dn));
828     }
830     /* Check generated gidNumber, it may be used by another group. 
831      */
832     if($this->gidNumber != ""){
833       $ldap->cd($this->config->current['BASE']);
834       $ldap->search("(&(!(cn=".$this->orig_cn."))(objectClass=posixGroup)(gidNumber=".$this->gidNumber."))",array("cn"));
835       if($ldap->count()){
836         $cns = "";
837         while($attrs = $ldap->fetch()){
838           $cns .= $attrs['cn'][0].", ";
839         }
840         $cns = rtrim($cns,", ");
841         msg_dialog::display(_("Warning"),sprintf(_("The gidNumber '%s' is already in use by %s!"),$this->gidNumber,$cns) , WARNING_DIALOG );
842       }
843     }
845     /* Write back to ldap */
846     $ldap->cd($this->dn);
847     $this->cleanup();
848     $ldap->$mode($this->attrs);
850     /* Remove ACL dependencies too,
851      */
852     if($this->dn != $this->orig_dn && $this->orig_dn != "new"){
853       $tmp = new acl($this->config,$this->parent,$this->dn);
854       $tmp->update_acl_membership($this->orig_dn,$this->dn);
855     }
857     if($this->initially_was_account){
858       new log("modify","groups/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
859     }else{
860       new log("create","groups/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
861     }
863     $ret= 0;
864     if (!$ldap->success()){
865       msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, 0, get_class()));
866       $ret= 1;
867     }
869     $this->trustModeDialog->dn = $this->dn;
870     $this->trustModeDialog->save();
872     /* Remove uid lock */
873     del_lock ("gidnumber");
875     /* Post that we've done*/
876     $this->handle_post_events($mode);
878     return ($ret);
879   }
881   function check()
882   {
883     /* Call common method to give check the hook */
884     $message= plugin::check();
886     /* Permissions for that base? */
887     if ($this->base != ""){
888       $new_dn= 'cn='.$this->cn.','.get_groups_ou().$this->base;
889     } else {
890       $new_dn= $this->dn;
891     }
893     /* must: cn */
894     if ($this->cn == "" && $this->acl_is_writeable("cn")){
895       $message[]= msgPool::required(_("Name"));
896     }
898     // Check if a wrong base was supplied
899     if(!$this->baseSelector->checkLastBaseUpdate()){
900       $message[]= msgPool::check_base();;
901     }
903     /* Check for valid input */
904     if (!tests::is_uid($this->cn)){
905       if (strict_uid_mode()){
906         $message[]= msgPool::invalid(_("Name"), $this->cn, "/[a-z0-9_-]/");
907       } else {
908         $message[]= msgPool::invalid(_("Name"), $this->cn, "/[a-z0-9_-]/i");
909       }
910     }
912     // Check if a wrong base was supplied
913     if(!$this->baseSelector->checkLastBaseUpdate()){
914       $message[]= msgPool::check_base();;
915     }
917     if($this->allowGroupsWithSameNameInOtherSubtrees == true){
919       /* Check for used 'cn' */
920       $ldap= $this->config->get_ldap_link();
921       if(($this->cn  != $this->orig_cn) || ($this->orig_dn == "new")){
922         $ldap->cd(get_groups_ou().$this->base);
923         $ldap->ls("(&(|(objectClass=gosaGroupOfNames)(objectClass=posixGroup))(cn=$this->cn))",get_groups_ou().$this->base,array("cn"));
924         if ($ldap->count() != 0){
925           $message[]= msgPool::duplicated(_("Name"));
926         }
927       }
929     }else{
931       /* Check for used 'cn' */
932       $ldap= $this->config->get_ldap_link();
933       $ldap->cd($this->config->current['BASE']);
934       $ldap->search("(&(|(objectClass=gosaGroupOfNames)(objectClass=posixGroup))(cn=$this->cn))",array("cn"));
935       if ($ldap->count() != 0){
937         /* New entry? */
938         if ($this->dn == 'new'){
939           $message[]= msgPool::duplicated(_("Name"));
940         }
942         /* Moved? */
943         elseif ($new_dn != $this->orig_dn){
944           $ldap->fetch();
945           if ($ldap->getDN() != $this->orig_dn){
946             $message[]= msgPool::duplicated(_("Name"));
947           }
948         }
949       }
950     }
951      
952     /* Check ID */
953     if ($this->force_gid == "1"){
954       if (!tests::is_id($this->gidNumber)){
955         $message[]= msgPool::invalid(_("GID"), $this->gidNumber, "/[0-9]/");
956       } else {
957         if ($this->gidNumber < $this->config->get_cfg_value("minId")){
958           $message[]= msgPool::toosmall(_("GID"), $this->config->get_cfg_value("minId"));
959         }
961       }
962     }
963     
964     /* Check if we are allowed to create or move this object 
965      */
966     if(!$this->orig_dn == "new" || 
967         $this->orig_base != $this->base || 
968         $this->cn != $this->orig_cn){
970       if($this->orig_dn == "new" && !$this->acl_is_createable($this->base)){
971         $message[] = msgPool::permCreate();
972       }elseif($this->orig_dn != "new" && !$this->acl_is_moveable($this->base)){
973         $message[] = msgPool::permMove();
974       }
975     }
977     return ($message);
978   }
981   function getCopyDialog()
982   {
983     $vars = array("cn");
984   
985     if($this ->force_gid){
986       $used = " checked ";
987       $dis  = "";
988     }else{
989       $used = "";
990       $dis  = " disabled ";
991     }
993     $smarty = get_smarty();
994     $smarty->assign("used",$used);
995     $smarty->assign("dis" ,$dis);
996     $smarty->assign("cn" ,$this->cn);
997     $smarty->assign("gidNumber",$this->gidNumber);
998     $str = $smarty->fetch(get_template_path("paste_generic.tpl",TRUE));
999     $ret = array();
1000     $ret['string'] = $str;
1001     $ret['status'] = "";
1002     return($ret);
1003   }
1005   function saveCopyDialog()
1006   {
1007     if(isset($_POST['cn'])){
1008       $this->cn = $_POST['cn'];
1009     }
1010     if(isset($_POST['force_gid'])){
1011       $this->force_gid  = 1;
1012       $this->gidNumber= $_POST['gidNumber'];
1013     }else{
1014       $this->force_gid  = 0;
1015       $this->gidNumber  = false;
1016     }
1017   }
1019   
1020   /* Return plugin informations for acl handling  */ 
1021   static function plInfo()
1022   {
1023     return (array(  
1024           "plShortName" => _("Generic"),
1025           "plDescription" => _("Generic group settings"),
1026           "plSelfModify"  => FALSE,
1027           "plDepends"     => array(),
1028           "plPriority"    => 0,
1029           "plSection"     => array("administration"),
1030           "plCategory"    => array("groups" => array("objectClass" => "posixGroup", "description" => _("Groups"))),
1032           "plProvidedAcls"    => array(
1033             "cn"                => _("Name"),
1034             "description"       => _("Description"),
1035             "base"              => _("Base"),
1037             "gidNumber"         => _("GID"),
1039             "sambaGroupType"    => _("Samba group type"),
1040             "sambaDomainName"   => _("Samba domain name"),
1041             "accessTo"        => _("System trust"),
1042             "fonGroup"          => _("Phone pickup group"),
1043             "nagiosGroup"       => _("Nagios group"),
1045             "memberUid"         => _("Group member"))
1046         ));
1047   }
1050   function multiple_save_object()
1051   {
1052     if(isset($_POST['group_mulitple_edit'])){
1054       /* Create a base backup and reset the
1055          base directly after calling plugin::save_object();
1056          Base will be set seperatly a few lines below */
1057       $base_tmp = $this->base;
1058       plugin::multiple_save_object();
1059       plugin::save_object();
1060       $this->trustModeDialog->multiple_save_object();
1061       $this->base = $base_tmp;
1063       foreach(array("base","smbgroup","groupType","sambaDomainName","fon_group","nagios_group") as $attr){
1064         if(isset($_POST['use_'.$attr])){
1065           $this->multi_boxes[] = $attr;
1066         }
1067       }
1069       /* Refresh base */
1070       if ($this->acl_is_moveable($this->base)){
1071         if (!$this->baseSelector->update()) {
1072           msg_dialog::display(_("Error"), msgPool::permMove(), ERROR_DIALOG);
1073         }
1074         if ($this->base != $this->baseSelector->getBase()) {
1075           $this->base= $this->baseSelector->getBase();
1076           $this->is_modified= TRUE;
1077         }
1078       }
1080       foreach (array( "smbgroup"   => "sambaGroupType" ,"nagios_group" => "nagiosGroup") as $val => $aclname) {
1081         if ($this->acl_is_writeable($aclname)){
1082           if(isset($_POST["$val"])){
1083             $this->$val=  TRUE;
1084           }else{
1085             $this->$val=  FALSE;
1086           }
1087         }
1088       }
1090       /* Save sambaDomain attribute */
1091       if ($this->acl_is_writeable("sambaDomainName") && isset ($_POST['sambaDomainName'])){
1092         $this->sambaDomainName= $_POST['sambaDomainName'];
1093         $this->groupType= $_POST['groupType'];
1094       }
1096       /* Save fon attribute */
1097       if ($this->acl_is_writeable("fonGroup")){
1098         if (isset ($_POST['fon_group'])){
1099           $this->fon_group= TRUE;
1100         } else {
1101           $this->fon_group= FALSE;
1102         }
1103       }
1104     }
1105   }
1108   function get_multi_edit_values()
1109   {
1110     $ret = plugin::get_multi_edit_values();
1111     $ret = array_merge($ret,$this->trustModeDialog->get_multi_edit_values());
1113     foreach(array("base","smbgroup","groupType","sambaDomainName","fon_group","nagios_group") as $attr){    
1114       if(in_array($attr,$this->multi_boxes)){
1115         $ret[$attr] = $this->$attr;
1116       }
1117     }
1119     $ret['memberUid'] = $this->memberUid;
1120     $ret['memberUid_used_by_some'] = $this->memberUid_used_by_some;
1121     return($ret);
1122   }
1124   function multiple_execute()
1125   {
1126     return($this->execute());
1127   }
1130   /* Initialize plugin with given atribute arrays
1131    */
1132   function init_multiple_support($attrs,$all)
1133   {
1134     plugin::init_multiple_support($attrs,$all);
1135     $this->trustModeDialog->init_multiple_support($attrs,$all);
1137     $this->memberUid = array();
1138     $this->memberUid_used_by_some = array();
1139     if (isset($attrs['memberUid'])){
1140       for ($i= 0; $i<$attrs['memberUid']['count']; $i++){
1141         $this->memberUid[$attrs['memberUid'][$i]]= $attrs['memberUid'][$i];
1142       }
1143       ksort($this->memberUid);
1144     }
1146     if (isset($all['memberUid'])){
1147       for ($i= 0; $i<$all['memberUid']['count']; $i++){
1148         if(!in_array($all['memberUid'][$i],$this->memberUid)){
1149           $this->memberUid_used_by_some[$all['memberUid'][$i]]= $all['memberUid'][$i];
1150         }
1151       }
1152       ksort($this->memberUid_used_by_some);
1153     }
1155     $this->reload(TRUE);
1157     // We've two lists in mutliple support  
1158     //  - one which represents those users which are part of ALL groups.
1159     //  - ond one which represents those users which are only part of SOME groups.
1160     $this->commonList = new sortableListing();
1161     $this->commonList->setDeleteable(true);
1162     $this->commonList->setInstantDelete(true);
1163     $this->commonList->setEditable(false);
1164     $this->commonList->setWidth("100%");
1165     $this->commonList->setHeight("120px");
1166     $this->commonList->setHeader(array('~',_("Given name"),_("Surename"),_("Uid")));
1167     $this->commonList->setColspecs(array('20px','*','*','*','20px'));
1168     $this->commonList->setDefaultSortColumn(1);
1170     $this->partialList = new sortableListing();
1171     $this->partialList->setDeleteable(true);
1172     $this->partialList->setInstantDelete(true);
1173     $this->partialList->setEditable(false);
1174     $this->partialList->setWidth("100%");
1175     $this->partialList->setHeight("120px");
1176     $this->partialList->setHeader(array('~',_("Given name"),_("Surename"),_("Uid")));
1177     $this->partialList->setColspecs(array('20px','*','*','*','20px'));
1178     $this->partialList->setDefaultSortColumn(1);
1179   }
1182   function PrepareForCopyPaste($source)
1183   {
1184     plugin::PrepareForCopyPaste($source);
1186     $this->trustModeDialog->PrepareForCopyPaste($source);
1188     if ($this->smbgroup) { 
1189       $this->sambaSID = $this->getSambaSID(); 
1190     } 
1192     $this->memberUid = array();
1193     if(isset($source['memberUid'])){
1194       for($i = 0 ; $i < $source['memberUid']['count']; $i ++){
1195         $this->memberUid[] = $source['memberUid'][$i];
1196       }
1197     }
1198   }
1201   function set_acl_base($base)
1202   {
1203     plugin::set_acl_base($base);
1204     $this->trustModeDialog->set_acl_base($base);
1205   }
1208   /*! \brief  Enables multiple support for this plugin
1209    */
1210   function enable_multiple_support()
1211   {
1212     plugin::enable_multiple_support();
1213     $this->trustModeDialog->enable_multiple_support();
1214   }
1217   function set_multi_edit_values($attrs)
1218   {
1219     $users = array();
1221     /* Update groupMembership, keep optinal group */
1222     foreach($attrs['memberUid_used_by_some'] as $uid){
1223       if(in_array($uid,$this->memberUid)){
1224         $users[$uid] = $uid;
1225       }
1226     }
1228     /* Update groupMembership, add forced groups */
1229     foreach($attrs['memberUid'] as $uid){
1230       $users[$uid] = $uid;
1231     }
1232     plugin::set_multi_edit_values($attrs);
1233     $this->trustModeDialog->set_multi_edit_values($attrs);
1234     $this->memberUid = $users;
1235   }
1238   /*! \brief Get a new SambaSID for a group */ 
1239   function getSambaSID() 
1240   { 
1241     $ldap = $this->config->get_ldap_link(); 
1242     $gidNumber= $this->gidNumber; 
1243     while(TRUE){ 
1244       $sid= $this->SID."-".($gidNumber*2 + $this->ridBase+1); 
1245       $ldap->cd($this->config->current['BASE']); 
1246       $ldap->search("(sambaSID=$sid)",array("sambaSID")); 
1247       if ($ldap->count() == 0){ 
1248         break; 
1249       } 
1250       $gidNumber++; 
1251     } 
1252   
1253     return $sid; 
1254   } 
1257 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1258 ?>