Code

ac7ebe894a93bd2c5cdd5056d139f546868753cb
[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     if ($this->dn == "new"){
172       if(session::is_set('CurrentMainBase')){
173         $this->base = session::get('CurrentMainBase');
174       }else{
175         $ui= get_userinfo();
176         $this->base= dn2base($ui->dn);
177       }
178     } else {
180       /* Get object base */
181       $this->base =preg_replace ("/^[^,]+,".preg_quote(get_groups_ou(), '/')."/i","",$this->dn);
182     }
183     $this->orig_base = $this->base;
185     /* This is always an account */
186     $this->is_account= TRUE;
188     /* Instanciate base selector */
189     $this->baseSelector= new baseSelector($this->get_allowed_bases(), $this->base);
190     $this->baseSelector->setSubmitButton(false);
191     $this->baseSelector->setHeight(300);
192     $this->baseSelector->update(true);
194     $this->reload(TRUE);
195   }
197   function execute()
198   {
199     /* Call parent execute */
200     plugin::execute();
202     /* Log view */
203     if($this->is_account && !$this->view_logged){
204       $this->view_logged = TRUE;
205       new log("view","groups/".get_class($this),$this->dn);
206     }
208     /* Do we represent a valid group? */
209     if (!$this->is_account && $this->parent === NULL){
210       $display= "<img alt=\"\" src=\"images/small-error.png\" align=\"middle\">&nbsp;<b>".msgPool::noValidExtension()."</b>";
211       return ($display);
212     }
214     /* Delete user from group */
215     if (isset($_POST['del_users']) && isset($_POST['members']) && preg_match("/w/",$this->getacl("memberUid"))){
216       foreach ($_POST['members'] as $value){
217         unset ($this->members["$value"]);
218         $this->removeUser($value);
219       }
220       $this->reload();
221     }
223     /* Add objects? */
224     if (isset($_POST["edit_membership"]) && preg_match("/w/",$this->getacl("memberUid"))){
225       $this->userSelect= new userSelect($this->config, get_userinfo());
226     }
228     /* Add objects finished? */
229     if (isset($_POST["add_users_cancel"])){
230       $this->userSelect= NULL;
231     }
233     /* Add user to group */
234     if (isset($_POST['add_users_finish']) && $this->userSelect){
235   
236       $users = $this->userSelect->detectPostActions();
237       if(isset($users['targets'])){
238         $headpage = $this->userSelect->getHeadpage();
239         foreach($users['targets'] as $dn){
240           $attrs = $headpage->getEntry($dn);
241           $value = $attrs['uid'][0];
242           $this->addUser($value);
243           $this->members["$value"]= $this->allusers[$value];
244           $this->reload();
245         }
246       }
247       $this->userSelect= NULL;
248     }
250     $smarty= get_smarty();
251  
252     // Handle trust mode dialog
253     $this->dialog = FALSE;
254     $trustModeDialog = $this->trustModeDialog->execute();
255     if($this->trustModeDialog->trustSelect){
256         $this->dialog = TRUE;
257         return($trustModeDialog);
258     }
259     $smarty->assign("trustModeDialog" , $trustModeDialog);
261     $smarty->assign("usePrototype", "true");
263     if($this->config->search("nagiosaccount", "CLASS",array('menu'))){
264       $smarty->assign("nagios",true);
265     }else{
266       $smarty->assign("nagios",false);
267     }
268     
269     if($this->config->search("phoneAccount", "CLASS",array('menu'))){
270       $smarty->assign("pickupGroup",true);
271     }else{
272       $smarty->assign("pickupGroup",false);
273     }
275     /* Manage object add dialog */
276     if ($this->userSelect){
277       $this->dialog = TRUE;
278       return($this->userSelect->execute());
279     }
281     /* Create base acls */
282     $smarty->assign("base", $this->baseSelector->render());
284     $domains= array();
285     foreach($this->config->data['SERVERS']['SAMBA'] as $name => $content){
286       $domains[$name]= $name;
287     }
288     $smarty->assign("sambaDomains", $domains);
289     $smarty->assign("sambaDomainName", $this->sambaDomainName);
290     $groupTypes= array(0 => _("Samba group"), 512 => _("Domain admins"), 513 => _("Domain users"),
291         514 => _("Domain guests"));
293     /* Don't loose special groups! If not key'ed above, add it to
294        the combo box... */      
295     if ($this->groupType >= 500 && $this->groupType <= 553 && !isset($groupTypes[$this->groupType])){
296       $groupTypes[$this->groupType]= sprintf(_("Special group (%d)"), $this->groupType);
297     }
299     $smarty->assign("groupTypes", $groupTypes);
300     $smarty->assign("groupType", $this->groupType);
301     
303     /* Members and users */
304     $smarty->assign("members", $this->members);
306     /* Checkboxes */
307     foreach (array("force_gid", "smbgroup") as $val){
308       if ($this->$val == "1"){
309         $smarty->assign("$val", "checked");
310       } else {
311         $smarty->assign("$val", "");
312       }
313     }
314     if ($this->force_gid != "1"){
315       $smarty->assign("forceMode", "disabled");
316     }else{
317       $smarty->assign("forceMode", "");
318     }
319     if ($this->fon_group){
320       $smarty->assign("fon_group", "checked");
321     } else {
322       $smarty->assign("fon_group", "");
323     }
325     if ($this->nagios_group){
326       $smarty->assign("nagios_group", "checked");
327     } else {
328       $smarty->assign("nagios_group", "");
329     }
331     /* Fields */
332     foreach (array("cn", "description", "gidNumber") as $val){
333       $smarty->assign("$val", $this->$val);
334     }
336     $tmp = $this->plInfo();
337     foreach($tmp['plProvidedAcls'] as $name => $translation){
338       $smarty->assign($name."ACL",$this->getacl($name));
339     }
340     
341     if($this->acl_is_writeable("base")){
342       $smarty->assign("baseSelect",true);
343     }else{
344       $smarty->assign("baseSelect",false);
345     }
347     /* Multiple edit handling */
348     $smarty->assign("multiple_support",$this->multiple_support_active);
349     $smarty->assign("memberUid_All",$this->memberUid);
350     $smarty->assign("memberUid_Some",$this->memberUid_used_by_some);
352     foreach($this->attributes as $val){
353       if(in_array($val,$this->multi_boxes)){
354         $smarty->assign("use_".$val,TRUE);
355       }else{
356         $smarty->assign("use_".$val,FALSE);
357       }
358     }
359     foreach(array("base","smbgroup","groupType","sambaDomainName","fon_group","nagios_group") as $val){
360       if(in_array($val,$this->multi_boxes)){
361         $smarty->assign("use_".$val,TRUE);
362       }else{
363         $smarty->assign("use_".$val,FALSE);
364       }
365     }
367     return($smarty->fetch (get_template_path('generic.tpl', TRUE)));
368   }
370   function addUser($uid)
371   {
372     /* In mutliple edit we have to handle two arrays.
373      *  memberUid               : Containing users used in all groups
374      *  memberUid_used_by_some  : Those which are not used in all groups
375      * So we have to remove the given $uid from the ..used_by_some array first.
376      */
377     if($this->multiple_support_active){
378       if(isset($this->memberUid_used_by_some[$uid])){
379         unset($this->memberUid_used_by_some[$uid]);
380       }
381     }  
383     /* Ensure that the requested object is known to the group class 
384      */
385     if(!isset($this->dnMapping[$uid])){
386       $ldap = $this->config->get_ldap_link();
387       $ldap->cd($this->config->current['BASE']);
388       $ldap->search("(&(objectClass=gosaAccount)(uid=".$uid."))",array("dn", "uid","sn","givenName"));
389       if($ldap->count() == 0 ){
390         msg_dialog::display(_("Error"), 
391             sprintf(_("Adding UID '%s' to group '%s' failed: cannot find user object!"), 
392               $uid,$this->cn), 
393             ERROR_DIALOG);
394         return;
395       }elseif($ldap->count() >= 2){
396         msg_dialog::display(_("Error"), 
397             sprintf(_("Add UID '%s' to group '%s' failed: UID is used more than once!"),
398               $uid,$this->cn), 
399             ERROR_DIALOG);
400         return;
401       }else{
402         while($attrs = $ldap->fetch()){
403           $this->dnMapping[$attrs['uid'][0]] = $attrs['dn'];
404           $this->members[$attrs['uid'][0]] = $this->createResultName($attrs);
405           $this->allusers[$attrs['uid'][0]]= $this->createResultName($attrs);
406         }
407       }
408     }
410     $this->memberUid[$uid]= $uid;
411   }
414   function removeUser($uid)
415   {
416     $temp= array();
417     if(isset($this->memberUid[$uid])){
418       unset($this->memberUid[$uid]);
419     }
421     /* We have two array contianing group members in multiple edit.
422      *  this->memberUid             : Groups used by all currently edited groups 
423      *  this->memberUid_used_by_some: Used by some 
424      * So we have to remove the specified uid from both arrays.
425      */
426     if($this->multiple_support_active){
427       if(isset($this->memberUid_used_by_some[$uid])){
428         unset($this->memberUid_used_by_some[$uid]);
429       }
430     }
431   }
433   /* Reload data */
434   function reload($silent = FALSE)
435   {
436     /* Prepare ldap link */
437     $ldap= $this->config->get_ldap_link();
438     $ldap->cd($this->config->current['BASE']);
441     /* Resolve still unresolved memberuids to fill the list with sn/giveName attributes 
442         (Store gathered sn/givenName informations in $this->allusers too, 
443          to be prepared when adding/deleting users)
444      */    
445     $filter = "";
446     if ($this->config->get_cfg_value("ldapFilterNestingLimit") == "" ||
447         count($this->memberUid) < $this->config->get_cfg_value("ldapFilterNestingLimit")){
448       foreach ($this->memberUid as $value){
449         if(!isset($this->members[$value])){
450           $filter .= "(uid=".normalizeLdap($value).")";
451         }
452       }
453     }
455     if(!empty($filter)){    
456       $ldap->cd($this->config->current['BASE']);
457       $ldap->search("(&(objectClass=gosaAccount)(|".$filter."))",array("dn", "uid","sn","givenName"));
458       while($attrs = $ldap->fetch()){
459         $this->dnMapping[$attrs['uid'][0]] = $attrs['dn'];
460         $this->members[$attrs['uid'][0]] = $this->createResultName($attrs);
461         $this->allusers[$attrs['uid'][0]]= $this->createResultName($attrs);
462       } 
463     }
464   
465     /* check if all uids are resolved */
466     if ($this->config->get_cfg_value("ldapFilterNestingLimit") == "" ||
467         count($this->memberUid) < $this->config->get_cfg_value("ldapFilterNestingLimit")){
468       foreach ($this->memberUid as $value){
469         if(!isset($this->members[$value])){
470           $this->members[$value] =  _("! unknown UID")." [".$value."]"; 
471         }
472       }  
473     }else{
474       foreach ($this->memberUid as $value){
475         $this->members[$value] = $value; 
476       }  
477     }
478   
479     /* Sort lists */
480     natcasesort($this->members);
481     reset($this->members);
482   }
485   /* Create display name, this was used so often that it is excluded into a seperate function */
486   function createResultName($attrs)
487   {
488     if (isset($attrs["givenName"][0]) && isset($attrs["sn"][0])){
489       $ret =  $attrs["sn"][0].", ".$attrs["givenName"][0]." [".$attrs["uid"][0]."]";
490     } else {
491       $ret= $attrs['uid'][0];
492     }
493     return($ret);
494   }
497   function remove_from_parent()
498   {
499     plugin::remove_from_parent();
501     $ldap= $this->config->get_ldap_link();
502     $ldap->rmdir($this->dn);
503     if (!$ldap->success()){
504       msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_DEL, get_class()));
505     }
507     new log("remove","groups/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
509     /* Delete references to object groups */
510     $ldap->cd ($this->config->current['BASE']);
511     $ldap->search ("(&(objectClass=gosaGroupOfNames)(member=".LDAP::prepare4filter($this->dn)."))", array("cn"));
512     while ($ldap->fetch()){
513       $og= new ogroup($this->config, $ldap->getDN());
514       unset($og->member[$this->dn]);
515       $og->save ();
516     }
518     /* Remove ACL dependencies too,
519      */
520     $ldap = $this->config->get_ldap_link();
521     $ldap->cd($this->config->current['BASE']);
522     $ldap->search("(&(objectClass=gosaAcl)(gosaAclEntry=*".base64_encode($this->dn)."*))",array("gosaAclEntry","dn"));
523     while($attrs = $ldap->fetch()){
524       $acl = new acl($this->config,$this->parent,$attrs['dn']);
525       foreach($acl->gosaAclEntry as $id => $entry){
526         foreach($entry['members'] as $m_id => $member){
527           if($m_id == "G:".$this->dn || $m_id == "U:".$this->dn){
528             unset($acl->gosaAclEntry[$id]['members'][$m_id]);
529             gosa_log("modify","groups/acl",$attrs['dn'],array(),sprintf("Removed acl for %s on object %s.",$this->dn,$attrs['dn']));
530           }
531         }
532       }
533       $acl->save();
534     }
536     /* Remove ACL dependencies, too */
537     acl::remove_acl_for($this->dn);
539     /* Send signal to the world that we've done */
540     $this->handle_post_events("remove");
541   }
544   /* Save data to object */
545   function save_object()
546   {
547     /* Save additional values for possible next step */
548     if (isset($_POST['groupedit'])){
550       /* Create a base backup and reset the 
551           base directly after calling plugin::save_object();  
552          Base will be set seperatly a few lines below */
553       $base_tmp = $this->base;
554       plugin::save_object();
555       $this->trustModeDialog->save_object();
556       $this->base = $base_tmp;
558       /* Refresh base */
559       if ($this->acl_is_moveable($this->base)){
560         if (!$this->baseSelector->update()) {
561           msg_dialog::display(_("Error"), msgPool::permMove(), ERROR_DIALOG);
562         }
563         if ($this->base != $this->baseSelector->getBase()) {
564           $this->base= $this->baseSelector->getBase();
565           $this->is_modified= TRUE;
566         }
567       }
569       $this->force_gid= 0;
571       /* Only reset sambagroup flag if we are able to write this flag */
572       if($this->acl_is_writeable("sambaGroupType")){
573         $this->smbgroup = 0;
574       }
576       foreach (array(
577             "force_gid"  => "gidNumber", 
578             "smbgroup"   => "sambaGroupType") as $val => $aclname) {
579         if ($this->acl_is_writeable($aclname)  && isset($_POST["$val"])){
580           $this->$val= $_POST["$val"];
581         }
582       }
584       /* Save sambaDomain attribute */
585       if ($this->acl_is_writeable("sambaDomainName") && isset ($_POST['sambaDomainName'])){
586         $this->sambaDomainName= $_POST['sambaDomainName'];
587         $this->groupType= $_POST['groupType'];
588       }
590       /* Save fon attribute */
591       if ($this->acl_is_writeable("fonGroup")){
592         if (isset ($_POST['fon_group'])){
593           $this->fon_group= TRUE;
594         } else {
595           $this->fon_group= FALSE;
596         }
597       }
598       if ($this->acl_is_writeable("nagiosGroup")){
599         if (isset ($_POST['nagios_group'])){
600           $this->nagios_group= TRUE;
601         } else {
602           $this->nagios_group= FALSE;
603         }
604       }
605     }
606   }
609   /* Save to LDAP */
610   function save()
611   {
613     /* ID handling */
614     if ($this->force_gid == 0){
615       if ($this->saved_gidNumber != ""){
616         $this->gidNumber= $this->saved_gidNumber;
617       } else {
618         /* Calculate new, lock uids */
619         $wait= 10;
620         while (get_lock("gidnumber") != ""){
621           sleep (1);
623           /* timed out? */
624           if ($wait-- == 0){
625             break;
626           }
627         }
628         add_lock ("gidnumber", "gosa");
629         $this->gidNumber= get_next_id("gidNumber", $this->dn);
630       }
631     }
632   
633     plugin::save(); 
635     /* Remove objectClass for samba/phone support */
636     $tmp= array();
637     for ($i= 0; $i<count($this->attrs["objectClass"]); $i++){
638       if ($this->attrs['objectClass'][$i] != 'sambaGroupMapping' &&
639           $this->attrs['objectClass'][$i] != 'sambaIdmapEntry' &&
640           $this->attrs['objectClass'][$i] != 'goFonPickupGroup' &&
641          $this->attrs['objectClass'][$i] != 'nagiosContactGroup'){
642         $tmp[]= $this->attrs['objectClass'][$i];
643       }
644     }
645     $this->attrs['objectClass']= $tmp;
646     $ldap= $this->config->get_ldap_link();
648     /* Add samba group functionality */
649     if ($this->smbgroup){
650   
651       /* Fixed undefined index ... 
652        */ 
653       $this->SID = $this->ridBase = "";
654       if(isset($this->config->data['SERVERS']['SAMBA'][$this->sambaDomainName]['SID'])){
655         $this->SID    = $this->config->data['SERVERS']['SAMBA'][$this->sambaDomainName]['SID'];
656       }else{
657         msg_dialog::display(_("Error"), sprintf(_("Cannot find any SID for '%s'!"), $this->sambaDomainName), ERROR_DIALOG);
658       }
659       if(isset($this->config->data['SERVERS']['SAMBA'][$this->sambaDomainName]['RIDBASE'])){
660         $this->ridBase= $this->config->data['SERVERS']['SAMBA'][$this->sambaDomainName]['RIDBASE']; 
661       }else{
662         msg_dialog::display(_("Error"), sprintf(_("Cannot find any RIDBASE for '%s'!"), $this->sambaDomainName), ERROR_DIALOG);
663       }
665       $this->attrs['objectClass'][]= 'sambaGroupMapping';
666       $this->attrs['sambaGroupType']= "2";
668       /* Check if we need to create a special entry */
669       if ($this->groupType == 0){
671         if ($this->sambaSID == "" || $this->oldgroupType != $this->groupType){
672           $sid = $this->getSambaSID();
673           $this->attrs['sambaSID']= $sid;
674           $this->sambaSID= $sid;
675         }
677       } else {
678         $this->attrs['sambaSID']=$this->SID."-".$this->groupType;
679       }
681       /* User wants me to fake the idMappings? This is useful for
682          making winbind resolve the group names in a reasonable amount
683          of time in combination with larger databases. */
684       if ($this->config->get_cfg_value("sambaidmapping") == "true"){
685         $this->attrs['objectClass'][]= "sambaIdmapEntry";
686       }
688     }
690     /* Add phone functionality */
691     if ($this->fon_group){
692       $this->attrs['objectClass'][]= "goFonPickupGroup";
693     }
695     /* Add nagios functionality */
696     if ($this->nagios_group){
697       $this->attrs['objectClass'][]= "nagiosContactGroup";
698     }
700     /* Take members array */
701     if (count ($this->memberUid)){
702       $this->attrs['memberUid']= array_values(array_unique($this->memberUid));
703     }
705     /* New accounts need proper 'dn', propagate it to remaining objects */
706     if ($this->dn == 'new'){
707       $this->dn= 'cn='.$this->cn.','.get_groups_ou().$this->base;
708     }
710     /* Add member dn's for RFC2307bis Support */
711     if ($this->rfc2307bis){
712       $this->attrs['member'] = array();
713       if (count($this->memberUid)){
714         foreach($this->attrs['memberUid'] as $uid) {
716           if(isset($this->dnMapping[$uid])){
717             $this->attrs['member'][]= $this->dnMapping[$uid];
718           }
719         }
720       } else {
721         $this->attrs['member'][]= $this->dn;
722       }
723     }
725     /* Save data. Using 'modify' implies that the entry is already present, use 'add' for
726        new entries. So do a check first... */
727     $ldap->cat ($this->dn, array('dn'));
728     if ($ldap->fetch()){
729       /* Modify needs array() to remove values :-( */
730       if (!count ($this->memberUid)){
731         $this->attrs['memberUid']= array();
732       }
733       if (!$this->smbgroup){
734         $this->attrs['sambaGroupType']= array();
735         $this->attrs['sambaSID']= array();
736       }
737       
738       $mode= "modify";
739     } else {
740       $mode= "add";
741       $ldap->cd($this->config->current['BASE']);
742       $ldap->create_missing_trees(preg_replace('/^[^,]+,/', '', $this->dn));
743     }
745     $this->trustModeDialog->dn = $this->dn;
746     $this->trustModeDialog->save();
748     /* Check generated gidNumber, it may be used by another group. 
749      */
750     if($this->gidNumber != ""){
751       $ldap->cd($this->config->current['BASE']);
752       $ldap->search("(&(!(cn=".$this->orig_cn."))(objectClass=posixGroup)(gidNumber=".$this->gidNumber."))",array("cn"));
753       if($ldap->count()){
754         $cns = "";
755         while($attrs = $ldap->fetch()){
756           $cns .= $attrs['cn'][0].", ";
757         }
758         $cns = rtrim($cns,", ");
759         msg_dialog::display(_("Warning"),sprintf(_("The gidNumber '%s' is already in use by %s!"),$this->gidNumber,$cns) , WARNING_DIALOG );
760       }
761     }
763     /* Write back to ldap */
764     $ldap->cd($this->dn);
765     $this->cleanup();
766     $ldap->$mode($this->attrs);
768     /* Remove ACL dependencies too,
769      */
770     if($this->dn != $this->orig_dn && $this->orig_dn != "new"){
771       $tmp = new acl($this->config,$this->parent,$this->dn);
772       $tmp->update_acl_membership($this->orig_dn,$this->dn);
773     }
775     if($this->initially_was_account){
776       new log("modify","groups/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
777     }else{
778       new log("create","groups/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
779     }
781     $ret= 0;
782     if (!$ldap->success()){
783       msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, 0, get_class()));
784       $ret= 1;
785     }
787     /* Remove uid lock */
788     del_lock ("gidnumber");
790     /* Post that we've done*/
791     $this->handle_post_events($mode);
793     return ($ret);
794   }
796   function check()
797   {
798     /* Call common method to give check the hook */
799     $message= plugin::check();
801     /* Permissions for that base? */
802     if ($this->base != ""){
803       $new_dn= 'cn='.$this->cn.','.get_groups_ou().$this->base;
804     } else {
805       $new_dn= $this->dn;
806     }
808     /* must: cn */
809     if ($this->cn == "" && $this->acl_is_writeable("cn")){
810       $message[]= msgPool::required(_("Name"));
811     }
813     // Check if a wrong base was supplied
814     if(!$this->baseSelector->checkLastBaseUpdate()){
815       $message[]= msgPool::check_base();;
816     }
818     /* Check for valid input */
819     if (!tests::is_uid($this->cn)){
820       if (strict_uid_mode()){
821         $message[]= msgPool::invalid(_("Name"), $this->cn, "/[a-z0-9_-]/");
822       } else {
823         $message[]= msgPool::invalid(_("Name"), $this->cn, "/[a-z0-9_-]/i");
824       }
825     }
827     // Check if a wrong base was supplied
828     if(!$this->baseSelector->checkLastBaseUpdate()){
829       $message[]= msgPool::check_base();;
830     }
832     if($this->allowGroupsWithSameNameInOtherSubtrees == true){
834       /* Check for used 'cn' */
835       $ldap= $this->config->get_ldap_link();
836       if(($this->cn  != $this->orig_cn) || ($this->orig_dn == "new")){
837         $ldap->cd(get_groups_ou().$this->base);
838         $ldap->ls("(&(|(objectClass=gosaGroupOfNames)(objectClass=posixGroup))(cn=$this->cn))",get_groups_ou().$this->base,array("cn"));
839         if ($ldap->count() != 0){
840           $message[]= msgPool::duplicated(_("Name"));
841         }
842       }
844     }else{
846       /* Check for used 'cn' */
847       $ldap= $this->config->get_ldap_link();
848       $ldap->cd($this->config->current['BASE']);
849       $ldap->search("(&(|(objectClass=gosaGroupOfNames)(objectClass=posixGroup))(cn=$this->cn))",array("cn"));
850       if ($ldap->count() != 0){
852         /* New entry? */
853         if ($this->dn == 'new'){
854           $message[]= msgPool::duplicated(_("Name"));
855         }
857         /* Moved? */
858         elseif ($new_dn != $this->orig_dn){
859           $ldap->fetch();
860           if ($ldap->getDN() != $this->orig_dn){
861             $message[]= msgPool::duplicated(_("Name"));
862           }
863         }
864       }
865     }
866      
867     /* Check ID */
868     if ($this->force_gid == "1"){
869       if (!tests::is_id($this->gidNumber)){
870         $message[]= msgPool::invalid(_("GID"), $this->gidNumber, "/[0-9]/");
871       } else {
872         if ($this->gidNumber < $this->config->get_cfg_value("minId")){
873           $message[]= msgPool::toosmall(_("GID"), $this->config->get_cfg_value("minId"));
874         }
876       }
877     }
878     
879     /* Check if we are allowed to create or move this object 
880      */
881     if(!$this->orig_dn == "new" || 
882         $this->orig_base != $this->base || 
883         $this->cn != $this->orig_cn){
885       if($this->orig_dn == "new" && !$this->acl_is_createable($this->base)){
886         $message[] = msgPool::permCreate();
887       }elseif($this->orig_dn != "new" && !$this->acl_is_moveable($this->base)){
888         $message[] = msgPool::permMove();
889       }
890     }
892     return ($message);
893   }
896   function getCopyDialog()
897   {
898     $vars = array("cn");
899   
900     if($this ->force_gid){
901       $used = " checked ";
902       $dis  = "";
903     }else{
904       $used = "";
905       $dis  = " disabled ";
906     }
908     $smarty = get_smarty();
909     $smarty->assign("used",$used);
910     $smarty->assign("dis" ,$dis);
911     $smarty->assign("cn" ,$this->cn);
912     $smarty->assign("gidNumber",$this->gidNumber);
913     $str = $smarty->fetch(get_template_path("paste_generic.tpl",TRUE));
914     $ret = array();
915     $ret['string'] = $str;
916     $ret['status'] = "";
917     return($ret);
918   }
920   function saveCopyDialog()
921   {
922     if(isset($_POST['cn'])){
923       $this->cn = $_POST['cn'];
924     }
925     if(isset($_POST['force_gid'])){
926       $this->force_gid  = 1;
927       $this->gidNumber= $_POST['gidNumber'];
928     }else{
929       $this->force_gid  = 0;
930       $this->gidNumber  = false;
931     }
932   }
934   
935   /* Return plugin informations for acl handling  */ 
936   static function plInfo()
937   {
938     return (array(  
939           "plShortName" => _("Generic"),
940           "plDescription" => _("Generic group settings"),
941           "plSelfModify"  => FALSE,
942           "plDepends"     => array(),
943           "plPriority"    => 0,
944           "plSection"     => array("administration"),
945           "plCategory"    => array("groups" => array("objectClass" => "posixGroup", "description" => _("Groups"))),
947           "plProvidedAcls"    => array(
948             "cn"                => _("Name"),
949             "description"       => _("Description"),
950             "base"              => _("Base"),
952             "gidNumber"         => _("GID"),
954             "sambaGroupType"    => _("Samba group type"),
955             "sambaDomainName"   => _("Samba domain name"),
956             "accessTo"        => _("System trust"),
957             "fonGroup"          => _("Phone pickup group"),
958             "nagiosGroup"       => _("Nagios group"),
960             "memberUid"         => _("Group member"))
961         ));
962   }
965   function multiple_save_object()
966   {
967     if(isset($_POST['group_mulitple_edit'])){
969       /* Create a base backup and reset the
970          base directly after calling plugin::save_object();
971          Base will be set seperatly a few lines below */
972       $base_tmp = $this->base;
973       plugin::multiple_save_object();
974       plugin::save_object();
975       $this->trustModeDialog->multiple_save_object();
976       $this->base = $base_tmp;
978       foreach(array("base","smbgroup","groupType","sambaDomainName","fon_group","nagios_group") as $attr){
979         if(isset($_POST['use_'.$attr])){
980           $this->multi_boxes[] = $attr;
981         }
982       }
984       /* Refresh base */
985       if ($this->acl_is_moveable($this->base)){
986         if (!$this->baseSelector->update()) {
987           msg_dialog::display(_("Error"), msgPool::permMove(), ERROR_DIALOG);
988         }
989         if ($this->base != $this->baseSelector->getBase()) {
990           $this->base= $this->baseSelector->getBase();
991           $this->is_modified= TRUE;
992         }
993       }
995       foreach (array( "smbgroup"   => "sambaGroupType" ,"nagios_group" => "nagios_group") as $val => $aclname) {
996         if ($this->acl_is_writeable($aclname)){
997           if(isset($_POST["$val"])){
998             $this->$val=  TRUE;
999           }else{
1000             $this->$val=  FALSE;
1001           }
1002         }
1003       }
1005       /* Save sambaDomain attribute */
1006       if ($this->acl_is_writeable("sambaDomainName") && isset ($_POST['sambaDomainName'])){
1007         $this->sambaDomainName= $_POST['sambaDomainName'];
1008         $this->groupType= $_POST['groupType'];
1009       }
1011       /* Save fon attribute */
1012       if ($this->acl_is_writeable("fonGroup")){
1013         if (isset ($_POST['fon_group'])){
1014           $this->fon_group= TRUE;
1015         } else {
1016           $this->fon_group= FALSE;
1017         }
1018       }
1019     }
1020   }
1023   function get_multi_edit_values()
1024   {
1025     $ret = plugin::get_multi_edit_values();
1026     $ret = array_merge($ret,$this->trustModeDialog->get_multi_edit_values());
1028     foreach(array("base","smbgroup","groupType","sambaDomainName","fon_group","nagios_group") as $attr){    
1029       if(in_array($attr,$this->multi_boxes)){
1030         $ret[$attr] = $this->$attr;
1031       }
1032     }
1034     $ret['memberUid'] = $this->memberUid;
1035     $ret['memberUid_used_by_some'] = $this->memberUid_used_by_some;
1036     return($ret);
1037   }
1039   function multiple_execute()
1040   {
1041     return($this->execute());
1042   }
1045   /* Initialize plugin with given atribute arrays
1046    */
1047   function init_multiple_support($attrs,$all)
1048   {
1049     plugin::init_multiple_support($attrs,$all);
1050     $this->trustModeDialog->init_multiple_support($attrs,$all);
1052     $this->memberUid = array();
1053     $this->memberUid_used_by_some = array();
1054     if (isset($attrs['memberUid'])){
1055       for ($i= 0; $i<$attrs['memberUid']['count']; $i++){
1056         $this->memberUid[$attrs['memberUid'][$i]]= $attrs['memberUid'][$i];
1057       }
1058       ksort($this->memberUid);
1059     }
1061     if (isset($all['memberUid'])){
1062       for ($i= 0; $i<$all['memberUid']['count']; $i++){
1063         if(!in_array($all['memberUid'][$i],$this->memberUid)){
1064           $this->memberUid_used_by_some[$all['memberUid'][$i]]= $all['memberUid'][$i];
1065         }
1066       }
1067       ksort($this->memberUid_used_by_some);
1068     }
1069   }
1072   function PrepareForCopyPaste($source)
1073   {
1074     plugin::PrepareForCopyPaste($source);
1076     $this->trustModeDialog->PrepareForCopyPaste($source);
1078     if ($this->smbgroup) { 
1079       $this->sambaSID = $this->getSambaSID(); 
1080     } 
1082     $this->memberUid = array();
1083     if(isset($source['memberUid'])){
1084       for($i = 0 ; $i < $source['memberUid']['count']; $i ++){
1085         $this->memberUid[] = $source['memberUid'][$i];
1086       }
1087     }
1088   }
1091   function set_acl_base($base)
1092   {
1093     plugin::set_acl_base($base);
1094     $this->trustModeDialog->set_acl_base($base);
1095   }
1098   /*! \brief  Enables multiple support for this plugin
1099    */
1100   function enable_multiple_support()
1101   {
1102     plugin::enable_multiple_support();
1103     $this->trustModeDialog->enable_multiple_support();
1104   }
1107   function set_multi_edit_values($attrs)
1108   {
1109     $users = array();
1111     /* Update groupMembership, keep optinal group */
1112     foreach($attrs['memberUid_used_by_some'] as $uid){
1113       if(in_array($uid,$this->memberUid)){
1114         $users[$uid] = $uid;
1115       }
1116     }
1118     /* Update groupMembership, add forced groups */
1119     foreach($attrs['memberUid'] as $uid){
1120       $users[$uid] = $uid;
1121     }
1122     plugin::set_multi_edit_values($attrs);
1123     $this->trustModeDialog->set_multi_edit_values($attrs);
1124     $this->memberUid = $users;
1125   }
1128   /*! \brief Get a new SambaSID for a group */ 
1129   function getSambaSID() 
1130   { 
1131     $ldap = $this->config->get_ldap_link(); 
1132     $gidNumber= $this->gidNumber; 
1133     while(TRUE){ 
1134       $sid= $this->SID."-".($gidNumber*2 + $this->ridBase+1); 
1135       $ldap->cd($this->config->current['BASE']); 
1136       $ldap->search("(sambaSID=$sid)",array("sambaSID")); 
1137       if ($ldap->count() == 0){ 
1138         break; 
1139       } 
1140       $gidNumber++; 
1141     } 
1142   
1143     return $sid; 
1144   } 
1147 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1148 ?>