Code

Updated trustModes
[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;
71   function group (&$config, $dn= NULL)
72   {
73      /* Set rfc2307bis flag */
74      if ($config->get_cfg_value("rfc2307bis") == "true"){
75        $this->rfc2307bis= TRUE;
76        $this->attributes[]= "member";
77        $this->objectclasses[]= "groupOfNames";
78      }
80     plugin::plugin ($config, $dn);
82     $this->trustModeDialog = new trustModeDialog($this->config, $this->dn,NULL);
83     $this->trustModeDialog->setAcl('groups/group');
85     /* Load attributes depending on the samba version */
86     $this->orig_dn= $dn;
87     $this->orig_cn= $this->cn;
89     /* Get member list */
90     if (isset($this->attrs['memberUid'][0])){
91       $tmp= array();
92       for ($i= 0; $i<$this->attrs['memberUid']['count']; $i++){
93         $tmp[$this->attrs['memberUid'][$i]]= $this->attrs['memberUid'][$i];
94       }
95       $this->memberUid= $tmp;
96       ksort ($this->memberUid);
97     }
99     /* Save gidNumber for later use */
100     if (isset($this->attrs['gidNumber'])){
101       $this->saved_gidNumber= $this->attrs['gidNumber'][0];
102     }
104     /* Is a samba group? */
105     if (isset($this->attrs['objectClass'])){
106       if (array_search ('sambaGroupMapping', $this->attrs['objectClass']) == FALSE ){
107         $this->smbgroup= FALSE;
108       } else {
109         $this->smbgroup= TRUE;
110         if (isset($this->attrs['sambaSID'])){
111           $this->sambaSID= $this->attrs['sambaSID'][0];
112         }
113       }
114       if (array_search ('goFonPickupGroup', $this->attrs['objectClass']) == FALSE ){
115         $this->fon_group= FALSE;
116       } else {
117         $this->fon_group= TRUE;
118       }
119       if (array_search ('nagiosContactGroup', $this->attrs['objectClass']) == FALSE ){
120         $this->nagios_group= FALSE;
121       } else {
122         $this->nagios_group= TRUE;
123       }
124     }
126     /* Set mail flag */
127     if (isset($this->attrs['objectClass']) && in_array('gosaMailAccount', $this->attrs['objectClass'])){
128       $this->has_mailAccount= TRUE;
129     }
131     /* Get samba Domain in case of samba 3 */
132     if ($this->sambaSID != ""){
133       $this->SID= preg_replace ("/-[^-]+$/", "", $this->sambaSID);
134       $ldap= $this->config->get_ldap_link();
135       $ldap->cd($this->config->current['BASE']);
136       $ldap->search ("(&(objectClass=sambaDomain)(sambaSID=$this->SID))",array("sambaAlgorithmicRidBase"));
137       if ($ldap->count() != 0){
138         $attrs= $ldap->fetch();
139         if(isset($attrs['sambaAlgorithmicRidBase'])){  
140           $this->ridBase= $attrs['sambaAlgorithmicRidBase'][0];  
141         } else {  
142           $this->ridBase= $this->config->get_cfg_value("sambaRidBase");
143         } 
145         /* Get domain name for SID */
146         $this->sambaDomainName= "DEFAULT";
147         foreach ($this->config->data['SERVERS']['SAMBA'] as $key => $val){
148           if ($val['SID'] == $this->SID){
149             $this->sambaDomainName= $key;
150             break;
151           }
152         }
153       } else {
154         if ($this->config->get_cfg_value("sambaRidBase") != ""){
155           $this->sambaDomainName= "DEFAULT";
156           $this->ridBase= $this->config->get_cfg_value("sambaRidBase");
157           $this->SID= $this->config->get_cfg_value("sid");
158         } else {
159           msg_dialog::display(_("Configuration error"), _("Cannot find group SID in your configuration!"), ERROR_DIALOG);
160         }
161       }
163       /* Get group type */
164       $this->groupType= (int)substr(strrchr($this->sambaSID, "-"), 1);
165       if ($this->groupType < 500 || $this->groupType > 553){
166         $this->groupType= 0;
167       }
168       $this->oldgroupType= $this->groupType;
169     }
171     /* Get global filter config */
172     if (!session::is_set("gufilter")){
173       $ui= get_userinfo();
174       $base= get_base_from_people($ui->dn);
175       $gufilter= array( "dselect"       => $base,
176           "regex"           => "*");
177       session::set("gufilter", $gufilter);
178     }
179     $gufilter= session::get('gufilter');
180     $gufilter['SubSearchGroup'] = false;
181     session::set('gufilter',$gufilter);
182   
183     if ($this->dn == "new"){
184       if(session::is_set('CurrentMainBase')){
185         $this->base = session::get('CurrentMainBase');
186       }else{
187         $ui= get_userinfo();
188         $this->base= dn2base($ui->dn);
189       }
190     } else {
192       /* Get object base */
193       $this->base =preg_replace ("/^[^,]+,".preg_quote(get_groups_ou(), '/')."/i","",$this->dn);
194     }
195     $this->orig_base = $this->base;
197     /* Get global filter config */
198     if (!session::is_set("sysfilter")){
199       $ui= get_userinfo();
200       $base= get_base_from_people($ui->dn);
201       $sysfilter= array( "depselect"       => $base,
202           "regex"           => "*");
203       session::set("sysfilter", $sysfilter);
204     }
206     /* This is always an account */
207     $this->is_account= TRUE;
209     /* Instanciate base selector */
210     $this->baseSelector= new baseSelector($this->get_allowed_bases(), $this->base);
211     $this->baseSelector->setSubmitButton(false);
212     $this->baseSelector->setHeight(300);
213     $this->baseSelector->update(true);
215     $this->reload(TRUE);
216   }
218   function execute()
219   {
220     /* Call parent execute */
221     plugin::execute();
223     /* Log view */
224     if($this->is_account && !$this->view_logged){
225       $this->view_logged = TRUE;
226       new log("view","groups/".get_class($this),$this->dn);
227     }
229     /* Do we represent a valid group? */
230     if (!$this->is_account && $this->parent === NULL){
231       $display= "<img alt=\"\" src=\"images/small-error.png\" align=\"middle\">&nbsp;<b>".msgPool::noValidExtension()."</b>";
232       return ($display);
233     }
235     /* Delete user from group */
236     if (isset($_POST['del_users']) && isset($_POST['members']) && preg_match("/w/",$this->getacl("memberUid"))){
237       foreach ($_POST['members'] as $value){
238         unset ($this->members["$value"]);
239         $this->removeUser($value);
240       }
241       $this->reload();
242     }
244     /* Add objects? */
245     if (isset($_POST["edit_membership"]) && preg_match("/w/",$this->getacl("memberUid"))){
246       $this->userSelect= new userSelect($this->config, get_userinfo());
247       $this->dialog= TRUE;
248     }
250     /* Add objects finished? */
251     if (isset($_POST["add_users_cancel"])){
252       $this->userSelect= NULL;
253       $this->dialog= FALSE;
254     }
256     /* Add user to group */
257     if (isset($_POST['add_users_finish']) && $this->userSelect){
258   
259       $users = $this->userSelect->detectPostActions();
260       if(isset($users['targets'])){
261         $headpage = $this->userSelect->getHeadpage();
262         foreach($users['targets'] as $dn){
263           $attrs = $headpage->getEntry($dn);
264           $value = $attrs['uid'][0];
265           $this->addUser($value);
266           $this->members["$value"]= $this->allusers[$value];
267           $this->reload();
268         }
269       }
270       $this->userSelect= NULL;
271       $this->dialog= FALSE;
272     }
274     /* Dialog handling */
275     if(is_object($this->dialog)){
276       /* Must be called before save_object */
277       $this->dialog->save_object();
279       if($this->dialog->isClosed()){
280         $this->dialog = false;
281       }elseif($this->dialog->isSelected()){
283         /* Check if selected base is valid */
284         $tmp = $this->get_allowed_bases();
285         if(isset($tmp[$this->dialog->isSelected()])){
286           $this->base = $this->dialog->isSelected();
287         }
288         $this->dialog= false;
289       }else{
290         return($this->dialog->execute());
291       }
292     }
294     $smarty= get_smarty();
296     // Handle trust mode dialog
297     $trustModeDialog = $this->trustModeDialog->execute();
298     if($this->trustModeDialog->trustSelect){
299         $this->dialog = TRUE;
300         return($trustModeDialog);
302     }
303     $this->dialog = FALSE;
304     $smarty->assign("trustModeDialog" , $trustModeDialog);
306     $smarty->assign("usePrototype", "true");
308     if($this->config->search("nagiosaccount", "CLASS",array('menu'))){
309       $smarty->assign("nagios",true);
310     }else{
311       $smarty->assign("nagios",false);
312     }
313     
314     if($this->config->search("phoneAccount", "CLASS",array('menu'))){
315       $smarty->assign("pickupGroup",true);
316     }else{
317       $smarty->assign("pickupGroup",false);
318     }
320     /* Manage object add dialog */
321     if ($this->userSelect){
322       return($this->userSelect->execute());
323     }
325     /* Create base acls */
326     $smarty->assign("base", $this->baseSelector->render());
328     $domains= array();
329     foreach($this->config->data['SERVERS']['SAMBA'] as $name => $content){
330       $domains[$name]= $name;
331     }
332     $smarty->assign("sambaDomains", $domains);
333     $smarty->assign("sambaDomainName", $this->sambaDomainName);
334     $groupTypes= array(0 => _("Samba group"), 512 => _("Domain admins"), 513 => _("Domain users"),
335         514 => _("Domain guests"));
337     /* Don't loose special groups! If not key'ed above, add it to
338        the combo box... */      
339     if ($this->groupType >= 500 && $this->groupType <= 553 && !isset($groupTypes[$this->groupType])){
340       $groupTypes[$this->groupType]= sprintf(_("Special group (%d)"), $this->groupType);
341     }
343     $smarty->assign("groupTypes", $groupTypes);
344     $smarty->assign("groupType", $this->groupType);
345     
347     /* Members and users */
348     $smarty->assign("members", $this->members);
350     /* Checkboxes */
351     foreach (array("force_gid", "smbgroup") as $val){
352       if ($this->$val == "1"){
353         $smarty->assign("$val", "checked");
354       } else {
355         $smarty->assign("$val", "");
356       }
357     }
358     if ($this->force_gid != "1"){
359       $smarty->assign("forceMode", "disabled");
360     }else{
361       $smarty->assign("forceMode", "");
362     }
363     if ($this->fon_group){
364       $smarty->assign("fon_group", "checked");
365     } else {
366       $smarty->assign("fon_group", "");
367     }
369     if ($this->nagios_group){
370       $smarty->assign("nagios_group", "checked");
371     } else {
372       $smarty->assign("nagios_group", "");
373     }
375     /* Fields */
376     foreach (array("cn", "description", "gidNumber") as $val){
377       $smarty->assign("$val", $this->$val);
378     }
380     $tmp = $this->plInfo();
381     foreach($tmp['plProvidedAcls'] as $name => $translation){
382       $smarty->assign($name."ACL",$this->getacl($name));
383     }
384     
385     if($this->acl_is_writeable("base")){
386       $smarty->assign("baseSelect",true);
387     }else{
388       $smarty->assign("baseSelect",false);
389     }
391     /* Show main page */
392     $smarty->assign("alphabet", generate_alphabet(10));
393     $smarty->assign("search_image", get_template_path('images/lists/search.png'));
394     $smarty->assign("launchimage", get_template_path('images/lists/action.png'));
395     $smarty->assign("tree_image", get_template_path('images/lists/search-subtree.png'));
396     $smarty->assign("deplist", $this->config->idepartments);
398     /* Multiple edit handling */
399     $smarty->assign("multiple_support",$this->multiple_support_active);
401     $smarty->assign("memberUid_All",$this->memberUid);
402     $smarty->assign("memberUid_Some",$this->memberUid_used_by_some);
404     foreach($this->attributes as $val){
405       if(in_array($val,$this->multi_boxes)){
406         $smarty->assign("use_".$val,TRUE);
407       }else{
408         $smarty->assign("use_".$val,FALSE);
409       }
410     }
411     foreach(array("base","smbgroup","groupType","sambaDomainName","fon_group","nagios_group") as $val){
412       if(in_array($val,$this->multi_boxes)){
413         $smarty->assign("use_".$val,TRUE);
414       }else{
415         $smarty->assign("use_".$val,FALSE);
416       }
417     }
419     return($smarty->fetch (get_template_path('generic.tpl', TRUE)));
420   }
422   function addUser($uid)
423   {
424     /* In mutliple edit we have to handle two arrays.
425      *  memberUid               : Containing users used in all groups
426      *  memberUid_used_by_some  : Those which are not used in all groups
427      * So we have to remove the given $uid from the ..used_by_some array first.
428      */
429     if($this->multiple_support_active){
430       if(isset($this->memberUid_used_by_some[$uid])){
431         unset($this->memberUid_used_by_some[$uid]);
432       }
433     }  
435     /* Ensure that the requested object is known to the group class 
436      */
437     if(!isset($this->dnMapping[$uid])){
438       $ldap = $this->config->get_ldap_link();
439       $ldap->cd($this->config->current['BASE']);
440       $ldap->search("(&(objectClass=gosaAccount)(uid=".$uid."))",array("dn", "uid","sn","givenName"));
441       if($ldap->count() == 0 ){
442         msg_dialog::display(_("Error"), 
443             sprintf(_("Adding UID '%s' to group '%s' failed: cannot find user object!"), 
444               $uid,$this->cn), 
445             ERROR_DIALOG);
446         return;
447       }elseif($ldap->count() >= 2){
448         msg_dialog::display(_("Error"), 
449             sprintf(_("Add UID '%s' to group '%s' failed: UID is used more than once!"),
450               $uid,$this->cn), 
451             ERROR_DIALOG);
452         return;
453       }else{
454         while($attrs = $ldap->fetch()){
455           $this->dnMapping[$attrs['uid'][0]] = $attrs['dn'];
456           $this->members[$attrs['uid'][0]] = $this->createResultName($attrs);
457           $this->allusers[$attrs['uid'][0]]= $this->createResultName($attrs);
458         }
459       }
460     }
462     $this->memberUid[$uid]= $uid;
463   }
466   function removeUser($uid)
467   {
468     $temp= array();
469     if(isset($this->memberUid[$uid])){
470       unset($this->memberUid[$uid]);
471     }
473     /* We have two array contianing group members in multiple edit.
474      *  this->memberUid             : Groups used by all currently edited groups 
475      *  this->memberUid_used_by_some: Used by some 
476      * So we have to remove the specified uid from both arrays.
477      */
478     if($this->multiple_support_active){
479       if(isset($this->memberUid_used_by_some[$uid])){
480         unset($this->memberUid_used_by_some[$uid]);
481       }
482     }
483   }
485   /* Reload data */
486   function reload($silent = FALSE)
487   {
488     /* Fix regex string */
489     $gufilter = session::get("gufilter");
490     $regex    = normalizeLdap($gufilter['regex']);
491     $MaxUser  = $this->OnlyShowFirstEntries;
493     /* Prepare ldap link */
494     $ldap= $this->config->get_ldap_link();
495     $ldap->cd($gufilter['dselect']);
498     /* Resolve still unresolved memberuids to fill the list with sn/giveName attributes 
499         (Store gathered sn/givenName informations in $this->allusers too, 
500          to be prepared when adding/deleting users)
501      */    
502     $filter = "";
503     if ($this->config->get_cfg_value("ldapFilterNestingLimit") == "" ||
504         count($this->memberUid) < $this->config->get_cfg_value("ldapFilterNestingLimit")){
505       foreach ($this->memberUid as $value){
506         if(!isset($this->members[$value])){
507           $filter .= "(uid=".normalizeLdap($value).")";
508         }
509       }
510     }
512     if(!empty($filter)){    
513       $ldap->cd($this->config->current['BASE']);
514       $ldap->search("(&(objectClass=gosaAccount)(|".$filter."))",array("dn", "uid","sn","givenName"));
515       while($attrs = $ldap->fetch()){
516         $this->dnMapping[$attrs['uid'][0]] = $attrs['dn'];
517         $this->members[$attrs['uid'][0]] = $this->createResultName($attrs);
518         $this->allusers[$attrs['uid'][0]]= $this->createResultName($attrs);
519       } 
520     }
521   
522     /* check if all uids are resolved */
523     if ($this->config->get_cfg_value("ldapFilterNestingLimit") == "" ||
524         count($this->memberUid) < $this->config->get_cfg_value("ldapFilterNestingLimit")){
525       foreach ($this->memberUid as $value){
526         if(!isset($this->members[$value])){
527           $this->members[$value] =  _("! unknown UID")." [".$value."]"; 
528         }
529       }  
530     }else{
531       foreach ($this->memberUid as $value){
532         $this->members[$value] = $value; 
533       }  
534     }
536     /* Create display list of users matching regex & filter 
537      */
538     $this->displayUsers = array();
539     $filter = "(&(objectClass=gosaAccount)(!(objectClass=gosaUserTemplate))(!(uid=*$))(|(uid=".$regex.")(sn=".$regex.")(givenName=".$regex.")))";
541     /* Search in current tree or within subtrees depending on the checkbox from filter section */
542     if($gufilter['SubSearchGroup']){
543       $flag = GL_SIZELIMIT | GL_SUBSEARCH;
544       $base = $gufilter['dselect'];
545     }else{
546       $flag = GL_SIZELIMIT ;
547       $base = get_people_ou().$gufilter['dselect'];
548     }
549     $i = 0;
550   
552     $res = get_list($filter,"users",$base,array("dn", "uid", "sn", "givenName"),$flag);
554     /* Fetch all users and skip already used users */
555     foreach($res as $attrs){
556       if(in_array($attrs['uid'][0], $this->memberUid)) {
557         continue;
558       }
559       $i ++;
560       if($i > $MaxUser) {
561         break;
562       }
563       $this->dnMapping[$attrs['uid'][0]]= $attrs["dn"];
564       $this->allusers[$attrs['uid'][0]]     = $this->createResultName($attrs);
565       $this->displayUsers[$attrs['uid'][0]] = $this->createResultName($attrs);
566     }
567   
568     /* If more than max users are found, display a message to warn the user */
569     if($i == $MaxUser && !$silent){
570       msg_dialog::display(_("Configuration error"), sprintf(_("Search returned too many results. Not displaying more than %s entries!"), $MaxUser), ERROR_DIALOG);
571     }
572     
573     /* Sort lists */
574     natcasesort($this->members);
575     reset($this->members);
576     natcasesort ($this->displayUsers);
577     reset ($this->displayUsers);
578   }
581   /* Create display name, this was used so often that it is excluded into a seperate function */
582   function createResultName($attrs)
583   {
584     if (isset($attrs["givenName"][0]) && isset($attrs["sn"][0])){
585       $ret =  $attrs["sn"][0].", ".$attrs["givenName"][0]." [".$attrs["uid"][0]."]";
586     } else {
587       $ret= $attrs['uid'][0];
588     }
589     return($ret);
590   }
593   function remove_from_parent()
594   {
595     plugin::remove_from_parent();
597     $ldap= $this->config->get_ldap_link();
598     $ldap->rmdir($this->dn);
599     if (!$ldap->success()){
600       msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_DEL, get_class()));
601     }
603     new log("remove","groups/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
605     /* Delete references to object groups */
606     $ldap->cd ($this->config->current['BASE']);
607     $ldap->search ("(&(objectClass=gosaGroupOfNames)(member=".LDAP::prepare4filter($this->dn)."))", array("cn"));
608     while ($ldap->fetch()){
609       $og= new ogroup($this->config, $ldap->getDN());
610       unset($og->member[$this->dn]);
611       $og->save ();
612     }
614     /* Remove ACL dependencies too,
615      */
616     $ldap = $this->config->get_ldap_link();
617     $ldap->cd($this->config->current['BASE']);
618     $ldap->search("(&(objectClass=gosaAcl)(gosaAclEntry=*".base64_encode($this->dn)."*))",array("gosaAclEntry","dn"));
619     while($attrs = $ldap->fetch()){
620       $acl = new acl($this->config,$this->parent,$attrs['dn']);
621       foreach($acl->gosaAclEntry as $id => $entry){
622         foreach($entry['members'] as $m_id => $member){
623           if($m_id == "G:".$this->dn || $m_id == "U:".$this->dn){
624             unset($acl->gosaAclEntry[$id]['members'][$m_id]);
625             gosa_log("modify","groups/acl",$attrs['dn'],array(),sprintf("Removed acl for %s on object %s.",$this->dn,$attrs['dn']));
626           }
627         }
628       }
629       $acl->save();
630     }
632     /* Remove ACL dependencies, too */
633     acl::remove_acl_for($this->dn);
635     /* Send signal to the world that we've done */
636     $this->handle_post_events("remove");
637   }
640   /* Save data to object */
641   function save_object()
642   {
643     /* Save additional values for possible next step */
644     if (isset($_POST['groupedit'])){
646       /* Create a base backup and reset the 
647           base directly after calling plugin::save_object();  
648          Base will be set seperatly a few lines below */
649       $base_tmp = $this->base;
650       plugin::save_object();
651       $this->trustModeDialog->save_object();
652       $this->base = $base_tmp;
654       /* Refresh base */
655       if ($this->acl_is_moveable($this->base)){
656         if (!$this->baseSelector->update()) {
657           msg_dialog::display(_("Error"), msgPool::permMove(), ERROR_DIALOG);
658         }
659         if ($this->base != $this->baseSelector->getBase()) {
660           $this->base= $this->baseSelector->getBase();
661           $this->is_modified= TRUE;
662         }
663       }
665       $this->force_gid= 0;
667       /* Only reset sambagroup flag if we are able to write this flag */
668       if($this->acl_is_writeable("sambaGroupType")){
669         $this->smbgroup = 0;
670       }
672       foreach (array(
673             "force_gid"  => "gidNumber", 
674             "smbgroup"   => "sambaGroupType") as $val => $aclname) {
675         if ($this->acl_is_writeable($aclname)  && isset($_POST["$val"])){
676           $this->$val= $_POST["$val"];
677         }
678       }
680       /* Save sambaDomain attribute */
681       if ($this->acl_is_writeable("sambaDomainName") && isset ($_POST['sambaDomainName'])){
682         $this->sambaDomainName= $_POST['sambaDomainName'];
683         $this->groupType= $_POST['groupType'];
684       }
686       /* Save fon attribute */
687       if ($this->acl_is_writeable("fonGroup")){
688         if (isset ($_POST['fon_group'])){
689           $this->fon_group= TRUE;
690         } else {
691           $this->fon_group= FALSE;
692         }
693       }
694       if ($this->acl_is_writeable("nagiosGroup")){
695         if (isset ($_POST['nagios_group'])){
696           $this->nagios_group= TRUE;
697         } else {
698           $this->nagios_group= FALSE;
699         }
700       }
701     }
702   }
705   /* Save to LDAP */
706   function save()
707   {
709     /* ID handling */
710     if ($this->force_gid == 0){
711       if ($this->saved_gidNumber != ""){
712         $this->gidNumber= $this->saved_gidNumber;
713       } else {
714         /* Calculate new, lock uids */
715         $wait= 10;
716         while (get_lock("gidnumber") != ""){
717           sleep (1);
719           /* timed out? */
720           if ($wait-- == 0){
721             break;
722           }
723         }
724         add_lock ("gidnumber", "gosa");
725         $this->gidNumber= get_next_id("gidNumber", $this->dn);
726       }
727     }
728   
729     plugin::save(); 
731     /* Remove objectClass for samba/phone support */
732     $tmp= array();
733     for ($i= 0; $i<count($this->attrs["objectClass"]); $i++){
734       if ($this->attrs['objectClass'][$i] != 'sambaGroupMapping' &&
735           $this->attrs['objectClass'][$i] != 'sambaIdmapEntry' &&
736           $this->attrs['objectClass'][$i] != 'goFonPickupGroup' &&
737          $this->attrs['objectClass'][$i] != 'nagiosContactGroup'){
738         $tmp[]= $this->attrs['objectClass'][$i];
739       }
740     }
741     $this->attrs['objectClass']= $tmp;
742     $ldap= $this->config->get_ldap_link();
744     /* Add samba group functionality */
745     if ($this->smbgroup){
746   
747       /* Fixed undefined index ... 
748        */ 
749       $this->SID = $this->ridBase = "";
750       if(isset($this->config->data['SERVERS']['SAMBA'][$this->sambaDomainName]['SID'])){
751         $this->SID    = $this->config->data['SERVERS']['SAMBA'][$this->sambaDomainName]['SID'];
752       }else{
753         msg_dialog::display(_("Error"), sprintf(_("Cannot find any SID for '%s'!"), $this->sambaDomainName), ERROR_DIALOG);
754       }
755       if(isset($this->config->data['SERVERS']['SAMBA'][$this->sambaDomainName]['RIDBASE'])){
756         $this->ridBase= $this->config->data['SERVERS']['SAMBA'][$this->sambaDomainName]['RIDBASE']; 
757       }else{
758         msg_dialog::display(_("Error"), sprintf(_("Cannot find any RIDBASE for '%s'!"), $this->sambaDomainName), ERROR_DIALOG);
759       }
761       $this->attrs['objectClass'][]= 'sambaGroupMapping';
762       $this->attrs['sambaGroupType']= "2";
764       /* Check if we need to create a special entry */
765       if ($this->groupType == 0){
767         if ($this->sambaSID == "" || $this->oldgroupType != $this->groupType){
768           $sid = $this->getSambaSID();
769           $this->attrs['sambaSID']= $sid;
770           $this->sambaSID= $sid;
771         }
773       } else {
774         $this->attrs['sambaSID']=$this->SID."-".$this->groupType;
775       }
777       /* User wants me to fake the idMappings? This is useful for
778          making winbind resolve the group names in a reasonable amount
779          of time in combination with larger databases. */
780       if ($this->config->get_cfg_value("sambaidmapping") == "true"){
781         $this->attrs['objectClass'][]= "sambaIdmapEntry";
782       }
784     }
786     /* Add phone functionality */
787     if ($this->fon_group){
788       $this->attrs['objectClass'][]= "goFonPickupGroup";
789     }
791     /* Add nagios functionality */
792     if ($this->nagios_group){
793       $this->attrs['objectClass'][]= "nagiosContactGroup";
794     }
796     /* Take members array */
797     if (count ($this->memberUid)){
798       $this->attrs['memberUid']= array_values(array_unique($this->memberUid));
799     }
801     /* New accounts need proper 'dn', propagate it to remaining objects */
802     if ($this->dn == 'new'){
803       $this->dn= 'cn='.$this->cn.','.get_groups_ou().$this->base;
804     }
806     /* Add member dn's for RFC2307bis Support */
807     if ($this->rfc2307bis){
808       $this->attrs['member'] = array();
809       if (count($this->memberUid)){
810         foreach($this->attrs['memberUid'] as $uid) {
812           if(isset($this->dnMapping[$uid])){
813             $this->attrs['member'][]= $this->dnMapping[$uid];
814           }
815         }
816       } else {
817         $this->attrs['member'][]= $this->dn;
818       }
819     }
821     /* Save data. Using 'modify' implies that the entry is already present, use 'add' for
822        new entries. So do a check first... */
823     $ldap->cat ($this->dn, array('dn'));
824     if ($ldap->fetch()){
825       /* Modify needs array() to remove values :-( */
826       if (!count ($this->memberUid)){
827         $this->attrs['memberUid']= array();
828       }
829       if (!$this->smbgroup){
830         $this->attrs['sambaGroupType']= array();
831         $this->attrs['sambaSID']= array();
832       }
833       
834       $mode= "modify";
835     } else {
836       $mode= "add";
837       $ldap->cd($this->config->current['BASE']);
838       $ldap->create_missing_trees(preg_replace('/^[^,]+,/', '', $this->dn));
839     }
841     $this->trustModeDialog->dn = $this->dn;
842     $this->trustModeDialog->save();
844     /* Check generated gidNumber, it may be used by another group. 
845      */
846     if($this->gidNumber != ""){
847       $ldap->cd($this->config->current['BASE']);
848       $ldap->search("(&(!(cn=".$this->orig_cn."))(objectClass=posixGroup)(gidNumber=".$this->gidNumber."))",array("cn"));
849       if($ldap->count()){
850         $cns = "";
851         while($attrs = $ldap->fetch()){
852           $cns .= $attrs['cn'][0].", ";
853         }
854         $cns = rtrim($cns,", ");
855         msg_dialog::display(_("Warning"),sprintf(_("The gidNumber '%s' is already in use by %s!"),$this->gidNumber,$cns) , WARNING_DIALOG );
856       }
857     }
859     /* Write back to ldap */
860     $ldap->cd($this->dn);
861     $this->cleanup();
862     $ldap->$mode($this->attrs);
864     /* Remove ACL dependencies too,
865      */
866     if($this->dn != $this->orig_dn && $this->orig_dn != "new"){
867       $tmp = new acl($this->config,$this->parent,$this->dn);
868       $tmp->update_acl_membership($this->orig_dn,$this->dn);
869     }
871     if($this->initially_was_account){
872       new log("modify","groups/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
873     }else{
874       new log("create","groups/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
875     }
877     $ret= 0;
878     if (!$ldap->success()){
879       msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, 0, get_class()));
880       $ret= 1;
881     }
883     /* Remove uid lock */
884     del_lock ("gidnumber");
886     /* Post that we've done*/
887     $this->handle_post_events($mode);
889     return ($ret);
890   }
892   function check()
893   {
894     /* Call common method to give check the hook */
895     $message= plugin::check();
897     /* Permissions for that base? */
898     if ($this->base != ""){
899       $new_dn= 'cn='.$this->cn.','.get_groups_ou().$this->base;
900     } else {
901       $new_dn= $this->dn;
902     }
904     /* must: cn */
905     if ($this->cn == "" && $this->acl_is_writeable("cn")){
906       $message[]= msgPool::required(_("Name"));
907     }
909     // Check if a wrong base was supplied
910     if(!$this->baseSelector->checkLastBaseUpdate()){
911       $message[]= msgPool::check_base();;
912     }
914     /* Check for valid input */
915     if (!tests::is_uid($this->cn)){
916       if (strict_uid_mode()){
917         $message[]= msgPool::invalid(_("Name"), $this->cn, "/[a-z0-9_-]/");
918       } else {
919         $message[]= msgPool::invalid(_("Name"), $this->cn, "/[a-z0-9_-]/i");
920       }
921     }
923     // Check if a wrong base was supplied
924     if(!$this->baseSelector->checkLastBaseUpdate()){
925       $message[]= msgPool::check_base();;
926     }
928     if($this->allowGroupsWithSameNameInOtherSubtrees == true){
930       /* Check for used 'cn' */
931       $ldap= $this->config->get_ldap_link();
932       if(($this->cn  != $this->orig_cn) || ($this->orig_dn == "new")){
933         $ldap->cd(get_groups_ou().$this->base);
934         $ldap->ls("(&(|(objectClass=gosaGroupOfNames)(objectClass=posixGroup))(cn=$this->cn))",get_groups_ou().$this->base,array("cn"));
935         if ($ldap->count() != 0){
936           $message[]= msgPool::duplicated(_("Name"));
937         }
938       }
940     }else{
942       /* Check for used 'cn' */
943       $ldap= $this->config->get_ldap_link();
944       $ldap->cd($this->config->current['BASE']);
945       $ldap->search("(&(|(objectClass=gosaGroupOfNames)(objectClass=posixGroup))(cn=$this->cn))",array("cn"));
946       if ($ldap->count() != 0){
948         /* New entry? */
949         if ($this->dn == 'new'){
950           $message[]= msgPool::duplicated(_("Name"));
951         }
953         /* Moved? */
954         elseif ($new_dn != $this->orig_dn){
955           $ldap->fetch();
956           if ($ldap->getDN() != $this->orig_dn){
957             $message[]= msgPool::duplicated(_("Name"));
958           }
959         }
960       }
961     }
962      
963     /* Check ID */
964     if ($this->force_gid == "1"){
965       if (!tests::is_id($this->gidNumber)){
966         $message[]= msgPool::invalid(_("GID"), $this->gidNumber, "/[0-9]/");
967       } else {
968         if ($this->gidNumber < $this->config->get_cfg_value("minId")){
969           $message[]= msgPool::toosmall(_("GID"), $this->config->get_cfg_value("minId"));
970         }
972       }
973     }
974     
975     /* Check if we are allowed to create or move this object 
976      */
977     if(!$this->orig_dn == "new" || 
978         $this->orig_base != $this->base || 
979         $this->cn != $this->orig_cn){
981       if($this->orig_dn == "new" && !$this->acl_is_createable($this->base)){
982         $message[] = msgPool::permCreate();
983       }elseif($this->orig_dn != "new" && !$this->acl_is_moveable($this->base)){
984         $message[] = msgPool::permMove();
985       }
986     }
988     return ($message);
989   }
992   function getCopyDialog()
993   {
994     $vars = array("cn");
995   
996     if($this ->force_gid){
997       $used = " checked ";
998       $dis  = "";
999     }else{
1000       $used = "";
1001       $dis  = " disabled ";
1002     }
1004     $smarty = get_smarty();
1005     $smarty->assign("used",$used);
1006     $smarty->assign("dis" ,$dis);
1007     $smarty->assign("cn" ,$this->cn);
1008     $smarty->assign("gidNumber",$this->gidNumber);
1009     $str = $smarty->fetch(get_template_path("paste_generic.tpl",TRUE));
1010     $ret = array();
1011     $ret['string'] = $str;
1012     $ret['status'] = "";
1013     return($ret);
1014   }
1016   function saveCopyDialog()
1017   {
1018     if(isset($_POST['cn'])){
1019       $this->cn = $_POST['cn'];
1020     }
1021     if(isset($_POST['force_gid'])){
1022       $this->force_gid  = 1;
1023       $this->gidNumber= $_POST['gidNumber'];
1024     }else{
1025       $this->force_gid  = 0;
1026       $this->gidNumber  = false;
1027     }
1028   }
1030   
1031   /* Return plugin informations for acl handling  */ 
1032   static function plInfo()
1033   {
1034     return (array(  
1035           "plShortName" => _("Generic"),
1036           "plDescription" => _("Generic group settings"),
1037           "plSelfModify"  => FALSE,
1038           "plDepends"     => array(),
1039           "plPriority"    => 0,
1040           "plSection"     => array("administration"),
1041           "plCategory"    => array("groups" => array("objectClass" => "posixGroup", "description" => _("Groups"))),
1043           "plProvidedAcls"    => array(
1044             "cn"                => _("Name"),
1045             "description"       => _("Description"),
1046             "base"              => _("Base"),
1048             "gidNumber"         => _("GID"),
1050             "sambaGroupType"    => _("Samba group type"),
1051             "sambaDomainName"   => _("Samba domain name"),
1052             "accessTo"        => _("System trust"),
1053             "fonGroup"          => _("Phone pickup group"),
1054             "nagiosGroup"       => _("Nagios group"),
1056             "memberUid"         => _("Group member"))
1057         ));
1058   }
1061   function multiple_save_object()
1062   {
1063     if(isset($_POST['group_mulitple_edit'])){
1065       /* Create a base backup and reset the
1066          base directly after calling plugin::save_object();
1067          Base will be set seperatly a few lines below */
1068       $base_tmp = $this->base;
1069       plugin::multiple_save_object();
1070       plugin::save_object();
1071       $this->trustModeDialog->multiple_save_object();
1072       $this->base = $base_tmp;
1074       foreach(array("base","smbgroup","groupType","sambaDomainName","fon_group","nagios_group") as $attr){
1075         if(isset($_POST['use_'.$attr])){
1076           $this->multi_boxes[] = $attr;
1077         }
1078       }
1080       /* Refresh base */
1081       if ($this->acl_is_moveable($this->base)){
1082         if (!$this->baseSelector->update()) {
1083           msg_dialog::display(_("Error"), msgPool::permMove(), ERROR_DIALOG);
1084         }
1085         if ($this->base != $this->baseSelector->getBase()) {
1086           $this->base= $this->baseSelector->getBase();
1087           $this->is_modified= TRUE;
1088         }
1089       }
1091       foreach (array( "smbgroup"   => "sambaGroupType" ,"nagios_group" => "nagios_group") as $val => $aclname) {
1092         if ($this->acl_is_writeable($aclname)){
1093           if(isset($_POST["$val"])){
1094             $this->$val=  TRUE;
1095           }else{
1096             $this->$val=  FALSE;
1097           }
1098         }
1099       }
1101       /* Save sambaDomain attribute */
1102       if ($this->acl_is_writeable("sambaDomainName") && isset ($_POST['sambaDomainName'])){
1103         $this->sambaDomainName= $_POST['sambaDomainName'];
1104         $this->groupType= $_POST['groupType'];
1105       }
1107       /* Save fon attribute */
1108       if ($this->acl_is_writeable("fonGroup")){
1109         if (isset ($_POST['fon_group'])){
1110           $this->fon_group= TRUE;
1111         } else {
1112           $this->fon_group= FALSE;
1113         }
1114       }
1115     }
1116   }
1119   function get_multi_edit_values()
1120   {
1121     $ret = plugin::get_multi_edit_values();
1122     $ret = array_merge($ret,$this->trustModeDialog->get_multi_edit_values());
1124     foreach(array("base","smbgroup","groupType","sambaDomainName","fon_group","nagios_group") as $attr){    
1125       if(in_array($attr,$this->multi_boxes)){
1126         $ret[$attr] = $this->$attr;
1127       }
1128     }
1130     $ret['memberUid'] = $this->memberUid;
1131     $ret['memberUid_used_by_some'] = $this->memberUid_used_by_some;
1132     return($ret);
1133   }
1135   function multiple_execute()
1136   {
1137     return($this->execute());
1138   }
1141   /* Initialize plugin with given atribute arrays
1142    */
1143   function init_multiple_support($attrs,$all)
1144   {
1145     plugin::init_multiple_support($attrs,$all);
1146     $this->trustModeDialog->init_multiple_support($attrs,$all);
1148     $this->memberUid = array();
1149     $this->memberUid_used_by_some = array();
1150     if (isset($attrs['memberUid'])){
1151       for ($i= 0; $i<$attrs['memberUid']['count']; $i++){
1152         $this->memberUid[$attrs['memberUid'][$i]]= $attrs['memberUid'][$i];
1153       }
1154       ksort($this->memberUid);
1155     }
1157     if (isset($all['memberUid'])){
1158       for ($i= 0; $i<$all['memberUid']['count']; $i++){
1159         if(!in_array($all['memberUid'][$i],$this->memberUid)){
1160           $this->memberUid_used_by_some[$all['memberUid'][$i]]= $all['memberUid'][$i];
1161         }
1162       }
1163       ksort($this->memberUid_used_by_some);
1164     }
1165   }
1168   function PrepareForCopyPaste($source)
1169   {
1170     plugin::PrepareForCopyPaste($source);
1172     $this->trustModeDialog->PrepareForCopyPaste($source);
1174     if ($this->smbgroup) { 
1175       $this->sambaSID = $this->getSambaSID(); 
1176     } 
1178     $this->memberUid = array();
1179     if(isset($source['memberUid'])){
1180       for($i = 0 ; $i < $source['memberUid']['count']; $i ++){
1181         $this->memberUid[] = $source['memberUid'][$i];
1182       }
1183     }
1184   }
1187   function set_acl_base($base)
1188   {
1189     plugin::set_acl_base($base);
1190     $this->trustModeDialog->set_acl_base($base);
1191   }
1194   /*! \brief  Enables multiple support for this plugin
1195    */
1196   function enable_multiple_support()
1197   {
1198     plugin::enable_multiple_support();
1199     $this->trustModeDialog->enable_multiple_support();
1200   }
1203   function set_multi_edit_values($attrs)
1204   {
1205     $users = array();
1207     /* Update groupMembership, keep optinal group */
1208     foreach($attrs['memberUid_used_by_some'] as $uid){
1209       if(in_array($uid,$this->memberUid)){
1210         $users[$uid] = $uid;
1211       }
1212     }
1214     /* Update groupMembership, add forced groups */
1215     foreach($attrs['memberUid'] as $uid){
1216       $users[$uid] = $uid;
1217     }
1218     plugin::set_multi_edit_values($attrs);
1219     $this->trustModeDialog->set_multi_edit_values($attrs);
1220     $this->memberUid = $users;
1221   }
1224   /*! \brief Get a new SambaSID for a group */ 
1225   function getSambaSID() 
1226   { 
1227     $ldap = $this->config->get_ldap_link(); 
1228     $gidNumber= $this->gidNumber; 
1229     while(TRUE){ 
1230       $sid= $this->SID."-".($gidNumber*2 + $this->ridBase+1); 
1231       $ldap->cd($this->config->current['BASE']); 
1232       $ldap->search("(sambaSID=$sid)",array("sambaSID")); 
1233       if ($ldap->count() == 0){ 
1234         break; 
1235       } 
1236       $gidNumber++; 
1237     } 
1238   
1239     return $sid; 
1240   } 
1243 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1244 ?>