Code

Replaced user list in 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;
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     // Prepare lists
195     $this->memberList = new sortableListing();
196     $this->memberList->setDeleteable(true);
197     $this->memberList->setInstantDelete(true);
198     $this->memberList->setEditable(false);
199     $this->memberList->setWidth("100%");
200     $this->memberList->setHeight("300px");
201     $this->memberList->setHeader(array('~',_("Given name"),_("Surename"),_("Uid")));
202     $this->memberList->setColspecs(array('20px','*','*','*','20px'));
203     $this->memberList->setDefaultSortColumn(1);
205     $this->reload(TRUE);
206   }
208   function execute()
209   {
210     /* Call parent execute */
211     plugin::execute();
213     /* Log view */
214     if($this->is_account && !$this->view_logged){
215       $this->view_logged = TRUE;
216       new log("view","groups/".get_class($this),$this->dn);
217     }
219     /* Do we represent a valid group? */
220     if (!$this->is_account && $this->parent === NULL){
221       $display= "<img alt=\"\" src=\"images/small-error.png\" align=\"middle\">&nbsp;<b>".msgPool::noValidExtension()."</b>";
222       return ($display);
223     }
225     /* Delete user from group */
226     $this->memberList->save_object();
227     $action = $this->memberList->getAction();
228     if($action['action'] == 'delete' && preg_match("/w/",$this->getacl("memberUid"))){
229       foreach ($action['targets'] as $id){
230         $value = $this->memberList->getKey($id);
231         unset ($this->members["$value"]);
232         $this->removeUser($value);
233       }
234       $this->reload();
235     }
237     /* Add objects? */
238     if (isset($_POST["edit_membership"]) && preg_match("/w/",$this->getacl("memberUid"))){
239       $this->userSelect= new userSelect($this->config, get_userinfo());
240     }
242     /* Add objects finished? */
243     if (isset($_POST["add_users_cancel"])){
244       $this->userSelect= NULL;
245     }
247     /* Add user to group */
248     if (isset($_POST['add_users_finish']) && $this->userSelect){
249   
250       $users = $this->userSelect->detectPostActions();
251       if(isset($users['targets'])){
252         $headpage = $this->userSelect->getHeadpage();
253         foreach($users['targets'] as $dn){
254           $attrs = $headpage->getEntry($dn);
255           $value = $attrs['uid'][0];
256           $this->addUser($value);
257           $this->members["$value"]= $this->allusers[$value];
258           $this->reload();
259         }
260       }
261       $this->userSelect= NULL;
262     }
264     $smarty= get_smarty();
265  
266     // Handle trust mode dialog
267     $this->dialog = FALSE;
268     $trustModeDialog = $this->trustModeDialog->execute();
269     if($this->trustModeDialog->trustSelect){
270         $this->dialog = TRUE;
271         return($trustModeDialog);
272     }
273     $smarty->assign("trustModeDialog" , $trustModeDialog);
275     $smarty->assign("usePrototype", "true");
277     if($this->config->search("nagiosaccount", "CLASS",array('menu'))){
278       $smarty->assign("nagios",true);
279     }else{
280       $smarty->assign("nagios",false);
281     }
282     
283     if($this->config->search("phoneAccount", "CLASS",array('menu'))){
284       $smarty->assign("pickupGroup",true);
285     }else{
286       $smarty->assign("pickupGroup",false);
287     }
289     /* Manage object add dialog */
290     if ($this->userSelect){
291       $this->dialog = TRUE;
292       return($this->userSelect->execute());
293     }
295     /* Create base acls */
296     $smarty->assign("base", $this->baseSelector->render());
298     $domains= array();
299     foreach($this->config->data['SERVERS']['SAMBA'] as $name => $content){
300       $domains[$name]= $name;
301     }
302     $smarty->assign("sambaDomains", $domains);
303     $smarty->assign("sambaDomainName", $this->sambaDomainName);
304     $groupTypes= array(0 => _("Samba group"), 512 => _("Domain admins"), 513 => _("Domain users"),
305         514 => _("Domain guests"));
307     /* Don't loose special groups! If not key'ed above, add it to
308        the combo box... */      
309     if ($this->groupType >= 500 && $this->groupType <= 553 && !isset($groupTypes[$this->groupType])){
310       $groupTypes[$this->groupType]= sprintf(_("Special group (%d)"), $this->groupType);
311     }
313     $smarty->assign("groupTypes", $groupTypes);
314     $smarty->assign("groupType", $this->groupType);
315     
317     /* Members and users */
318     $this->memberList->setAcl($this->getacl("memberUid"));
319     $data = $lData = array();
321     foreach($this->members as $uid => $member){
322         
323         $data[$uid] = $member;
324         $givenName = $sn = _("Unknown");
325         if(isset($member['sn'][0])) $sn = $member['sn'][0];
326         if(isset($member['givenName'][0])) $givenName = $member['givenName'][0];
327         
328         $image = image('images/false.png');
329         if(isset($member['sn'])){
330             $image = image('plugins/users/images/select_user.png');
331         }
333         $lData[$uid] = array('data' => array($image,$sn, $givenName, $uid));
334     }
336     $this->memberList->setListData($data,$lData);
337     $this->memberList->update();
339     $smarty->assign("memberList", $this->memberList->render());
341     /* Checkboxes */
342     foreach (array("force_gid", "smbgroup") as $val){
343       if ($this->$val == "1"){
344         $smarty->assign("$val", "checked");
345       } else {
346         $smarty->assign("$val", "");
347       }
348     }
349     if ($this->force_gid != "1"){
350       $smarty->assign("forceMode", "disabled");
351     }else{
352       $smarty->assign("forceMode", "");
353     }
354     if ($this->fon_group){
355       $smarty->assign("fon_group", "checked");
356     } else {
357       $smarty->assign("fon_group", "");
358     }
360     if ($this->nagios_group){
361       $smarty->assign("nagios_group", "checked");
362     } else {
363       $smarty->assign("nagios_group", "");
364     }
366     /* Fields */
367     foreach (array("cn", "description", "gidNumber") as $val){
368       $smarty->assign("$val", $this->$val);
369     }
371     $tmp = $this->plInfo();
372     foreach($tmp['plProvidedAcls'] as $name => $translation){
373       $smarty->assign($name."ACL",$this->getacl($name));
374     }
375     
376     if($this->acl_is_writeable("base")){
377       $smarty->assign("baseSelect",true);
378     }else{
379       $smarty->assign("baseSelect",false);
380     }
382     /* Multiple edit handling */
383     $smarty->assign("multiple_support",$this->multiple_support_active);
384     $smarty->assign("memberUid_All",$this->memberUid);
385     $smarty->assign("memberUid_Some",$this->memberUid_used_by_some);
387     foreach($this->attributes as $val){
388       if(in_array($val,$this->multi_boxes)){
389         $smarty->assign("use_".$val,TRUE);
390       }else{
391         $smarty->assign("use_".$val,FALSE);
392       }
393     }
394     foreach(array("base","smbgroup","groupType","sambaDomainName","fon_group","nagios_group") as $val){
395       if(in_array($val,$this->multi_boxes)){
396         $smarty->assign("use_".$val,TRUE);
397       }else{
398         $smarty->assign("use_".$val,FALSE);
399       }
400     }
402     return($smarty->fetch (get_template_path('generic.tpl', TRUE)));
403   }
405   function addUser($uid)
406   {
407     /* In mutliple edit we have to handle two arrays.
408      *  memberUid               : Containing users used in all groups
409      *  memberUid_used_by_some  : Those which are not used in all groups
410      * So we have to remove the given $uid from the ..used_by_some array first.
411      */
412     if($this->multiple_support_active){
413       if(isset($this->memberUid_used_by_some[$uid])){
414         unset($this->memberUid_used_by_some[$uid]);
415       }
416     }  
418     /* Ensure that the requested object is known to the group class 
419      */
420     if(!isset($this->dnMapping[$uid])){
421       $ldap = $this->config->get_ldap_link();
422       $ldap->cd($this->config->current['BASE']);
423       $ldap->search("(&(objectClass=gosaAccount)(uid=".$uid."))",array("dn", "uid","sn","givenName"));
424       if($ldap->count() == 0 ){
425         msg_dialog::display(_("Error"), 
426             sprintf(_("Adding UID '%s' to group '%s' failed: cannot find user object!"), 
427               $uid,$this->cn), 
428             ERROR_DIALOG);
429         return;
430       }elseif($ldap->count() >= 2){
431         msg_dialog::display(_("Error"), 
432             sprintf(_("Add UID '%s' to group '%s' failed: UID is used more than once!"),
433               $uid,$this->cn), 
434             ERROR_DIALOG);
435         return;
436       }else{
437         while($attrs = $ldap->fetch()){
438           $this->dnMapping[$attrs['uid'][0]] = $attrs['dn'];
439           $this->members[$attrs['uid'][0]] = $attrs;
440           $this->allusers[$attrs['uid'][0]]= $atrts;
441         }
442       }
443     }
445     $this->memberUid[$uid]= $uid;
446   }
449   function removeUser($uid)
450   {
451     $temp= array();
452     if(isset($this->memberUid[$uid])){
453       unset($this->memberUid[$uid]);
454     }
456     /* We have two array contianing group members in multiple edit.
457      *  this->memberUid             : Groups used by all currently edited groups 
458      *  this->memberUid_used_by_some: Used by some 
459      * So we have to remove the specified uid from both arrays.
460      */
461     if($this->multiple_support_active){
462       if(isset($this->memberUid_used_by_some[$uid])){
463         unset($this->memberUid_used_by_some[$uid]);
464       }
465     }
466   }
468   /* Reload data */
469   function reload($silent = FALSE)
470   {
471     /* Prepare ldap link */
472     $ldap= $this->config->get_ldap_link();
473     $ldap->cd($this->config->current['BASE']);
476     /* Resolve still unresolved memberuids to fill the list with sn/giveName attributes 
477         (Store gathered sn/givenName informations in $this->allusers too, 
478          to be prepared when adding/deleting users)
479      */    
480     $filter = "";
481     if ($this->config->get_cfg_value("ldapFilterNestingLimit") == "" ||
482         count($this->memberUid) < $this->config->get_cfg_value("ldapFilterNestingLimit")){
483       foreach ($this->memberUid as $value){
484         if(!isset($this->members[$value])){
485           $filter .= "(uid=".normalizeLdap($value).")";
486         }
487       }
488     }
490     if(!empty($filter)){    
491       $ldap->cd($this->config->current['BASE']);
492       $ldap->search("(&(objectClass=gosaAccount)(|".$filter."))",array("dn", "uid","sn","givenName"));
493       while($attrs = $ldap->fetch()){
494         $this->dnMapping[$attrs['uid'][0]] = $attrs['dn'];
495         $this->members[$attrs['uid'][0]] = $attrs;
496         $this->allusers[$attrs['uid'][0]]= $attrs;
497       } 
498     }
499   
500     /* check if all uids are resolved */
501     if ($this->config->get_cfg_value("ldapFilterNestingLimit") == "" ||
502         count($this->memberUid) < $this->config->get_cfg_value("ldapFilterNestingLimit")){
503       foreach ($this->memberUid as $value){
504         if(!isset($this->members[$value])){
505           $this->members[$value] = "";
506         }
507       }  
508     }else{
509       foreach ($this->memberUid as $value){
510         $this->members[$value] = "";
511       }  
512     }
513   }
516   /* Create display name, this was used so often that it is excluded into a seperate function */
517   function createResultName($attrs)
518   {
519     if (isset($attrs["givenName"][0]) && isset($attrs["sn"][0])){
520       $ret =  $attrs["sn"][0].", ".$attrs["givenName"][0]." [".$attrs["uid"][0]."]";
521     } else {
522       $ret= $attrs['uid'][0];
523     }
524     return($ret);
525   }
528   function remove_from_parent()
529   {
530     plugin::remove_from_parent();
532     $ldap= $this->config->get_ldap_link();
533     $ldap->rmdir($this->dn);
534     if (!$ldap->success()){
535       msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_DEL, get_class()));
536     }
538     new log("remove","groups/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
540     /* Delete references to object groups */
541     $ldap->cd ($this->config->current['BASE']);
542     $ldap->search ("(&(objectClass=gosaGroupOfNames)(member=".LDAP::prepare4filter($this->dn)."))", array("cn"));
543     while ($ldap->fetch()){
544       $og= new ogroup($this->config, $ldap->getDN());
545       unset($og->member[$this->dn]);
546       $og->save ();
547     }
549     /* Remove ACL dependencies too,
550      */
551     $ldap = $this->config->get_ldap_link();
552     $ldap->cd($this->config->current['BASE']);
553     $ldap->search("(&(objectClass=gosaAcl)(gosaAclEntry=*".base64_encode($this->dn)."*))",array("gosaAclEntry","dn"));
554     while($attrs = $ldap->fetch()){
555       $acl = new acl($this->config,$this->parent,$attrs['dn']);
556       foreach($acl->gosaAclEntry as $id => $entry){
557         foreach($entry['members'] as $m_id => $member){
558           if($m_id == "G:".$this->dn || $m_id == "U:".$this->dn){
559             unset($acl->gosaAclEntry[$id]['members'][$m_id]);
560             gosa_log("modify","groups/acl",$attrs['dn'],array(),sprintf("Removed acl for %s on object %s.",$this->dn,$attrs['dn']));
561           }
562         }
563       }
564       $acl->save();
565     }
567     /* Remove ACL dependencies, too */
568     acl::remove_acl_for($this->dn);
570     /* Send signal to the world that we've done */
571     $this->handle_post_events("remove");
572   }
575   /* Save data to object */
576   function save_object()
577   {
578     /* Save additional values for possible next step */
579     if (isset($_POST['groupedit'])){
581       /* Create a base backup and reset the 
582           base directly after calling plugin::save_object();  
583          Base will be set seperatly a few lines below */
584       $base_tmp = $this->base;
585       plugin::save_object();
586       $this->trustModeDialog->save_object();
587       $this->base = $base_tmp;
589       /* Refresh base */
590       if ($this->acl_is_moveable($this->base)){
591         if (!$this->baseSelector->update()) {
592           msg_dialog::display(_("Error"), msgPool::permMove(), ERROR_DIALOG);
593         }
594         if ($this->base != $this->baseSelector->getBase()) {
595           $this->base= $this->baseSelector->getBase();
596           $this->is_modified= TRUE;
597         }
598       }
600       $this->force_gid= 0;
602       /* Only reset sambagroup flag if we are able to write this flag */
603       if($this->acl_is_writeable("sambaGroupType")){
604         $this->smbgroup = 0;
605       }
607       foreach (array(
608             "force_gid"  => "gidNumber", 
609             "smbgroup"   => "sambaGroupType") as $val => $aclname) {
610         if ($this->acl_is_writeable($aclname)  && isset($_POST["$val"])){
611           $this->$val= $_POST["$val"];
612         }
613       }
615       /* Save sambaDomain attribute */
616       if ($this->acl_is_writeable("sambaDomainName") && isset ($_POST['sambaDomainName'])){
617         $this->sambaDomainName= $_POST['sambaDomainName'];
618         $this->groupType= $_POST['groupType'];
619       }
621       /* Save fon attribute */
622       if ($this->acl_is_writeable("fonGroup")){
623         if (isset ($_POST['fon_group'])){
624           $this->fon_group= TRUE;
625         } else {
626           $this->fon_group= FALSE;
627         }
628       }
629       if ($this->acl_is_writeable("nagiosGroup")){
630         if (isset ($_POST['nagios_group'])){
631           $this->nagios_group= TRUE;
632         } else {
633           $this->nagios_group= FALSE;
634         }
635       }
636     }
637   }
640   /* Save to LDAP */
641   function save()
642   {
644     /* ID handling */
645     if ($this->force_gid == 0){
646       if ($this->saved_gidNumber != ""){
647         $this->gidNumber= $this->saved_gidNumber;
648       } else {
649         /* Calculate new, lock uids */
650         $wait= 10;
651         while (get_lock("gidnumber") != ""){
652           sleep (1);
654           /* timed out? */
655           if ($wait-- == 0){
656             break;
657           }
658         }
659         add_lock ("gidnumber", "gosa");
660         $this->gidNumber= get_next_id("gidNumber", $this->dn);
661       }
662     }
663   
664     plugin::save(); 
666     /* Remove objectClass for samba/phone support */
667     $tmp= array();
668     for ($i= 0; $i<count($this->attrs["objectClass"]); $i++){
669       if ($this->attrs['objectClass'][$i] != 'sambaGroupMapping' &&
670           $this->attrs['objectClass'][$i] != 'sambaIdmapEntry' &&
671           $this->attrs['objectClass'][$i] != 'goFonPickupGroup' &&
672          $this->attrs['objectClass'][$i] != 'nagiosContactGroup'){
673         $tmp[]= $this->attrs['objectClass'][$i];
674       }
675     }
676     $this->attrs['objectClass']= $tmp;
677     $ldap= $this->config->get_ldap_link();
679     /* Add samba group functionality */
680     if ($this->smbgroup){
681   
682       /* Fixed undefined index ... 
683        */ 
684       $this->SID = $this->ridBase = "";
685       if(isset($this->config->data['SERVERS']['SAMBA'][$this->sambaDomainName]['SID'])){
686         $this->SID    = $this->config->data['SERVERS']['SAMBA'][$this->sambaDomainName]['SID'];
687       }else{
688         msg_dialog::display(_("Error"), sprintf(_("Cannot find any SID for '%s'!"), $this->sambaDomainName), ERROR_DIALOG);
689       }
690       if(isset($this->config->data['SERVERS']['SAMBA'][$this->sambaDomainName]['RIDBASE'])){
691         $this->ridBase= $this->config->data['SERVERS']['SAMBA'][$this->sambaDomainName]['RIDBASE']; 
692       }else{
693         msg_dialog::display(_("Error"), sprintf(_("Cannot find any RIDBASE for '%s'!"), $this->sambaDomainName), ERROR_DIALOG);
694       }
696       $this->attrs['objectClass'][]= 'sambaGroupMapping';
697       $this->attrs['sambaGroupType']= "2";
699       /* Check if we need to create a special entry */
700       if ($this->groupType == 0){
702         if ($this->sambaSID == "" || $this->oldgroupType != $this->groupType){
703           $sid = $this->getSambaSID();
704           $this->attrs['sambaSID']= $sid;
705           $this->sambaSID= $sid;
706         }
708       } else {
709         $this->attrs['sambaSID']=$this->SID."-".$this->groupType;
710       }
712       /* User wants me to fake the idMappings? This is useful for
713          making winbind resolve the group names in a reasonable amount
714          of time in combination with larger databases. */
715       if ($this->config->get_cfg_value("sambaidmapping") == "true"){
716         $this->attrs['objectClass'][]= "sambaIdmapEntry";
717       }
719     }
721     /* Add phone functionality */
722     if ($this->fon_group){
723       $this->attrs['objectClass'][]= "goFonPickupGroup";
724     }
726     /* Add nagios functionality */
727     if ($this->nagios_group){
728       $this->attrs['objectClass'][]= "nagiosContactGroup";
729     }
731     /* Take members array */
732     if (count ($this->memberUid)){
733       $this->attrs['memberUid']= array_values(array_unique($this->memberUid));
734     }
736     /* New accounts need proper 'dn', propagate it to remaining objects */
737     if ($this->dn == 'new'){
738       $this->dn= 'cn='.$this->cn.','.get_groups_ou().$this->base;
739     }
741     /* Add member dn's for RFC2307bis Support */
742     if ($this->rfc2307bis){
743       $this->attrs['member'] = array();
744       if (count($this->memberUid)){
745         foreach($this->attrs['memberUid'] as $uid) {
747           if(isset($this->dnMapping[$uid])){
748             $this->attrs['member'][]= $this->dnMapping[$uid];
749           }
750         }
751       } else {
752         $this->attrs['member'][]= $this->dn;
753       }
754     }
756     /* Save data. Using 'modify' implies that the entry is already present, use 'add' for
757        new entries. So do a check first... */
758     $ldap->cat ($this->dn, array('dn'));
759     if ($ldap->fetch()){
760       /* Modify needs array() to remove values :-( */
761       if (!count ($this->memberUid)){
762         $this->attrs['memberUid']= array();
763       }
764       if (!$this->smbgroup){
765         $this->attrs['sambaGroupType']= array();
766         $this->attrs['sambaSID']= array();
767       }
768       
769       $mode= "modify";
770     } else {
771       $mode= "add";
772       $ldap->cd($this->config->current['BASE']);
773       $ldap->create_missing_trees(preg_replace('/^[^,]+,/', '', $this->dn));
774     }
776     $this->trustModeDialog->dn = $this->dn;
777     $this->trustModeDialog->save();
779     /* Check generated gidNumber, it may be used by another group. 
780      */
781     if($this->gidNumber != ""){
782       $ldap->cd($this->config->current['BASE']);
783       $ldap->search("(&(!(cn=".$this->orig_cn."))(objectClass=posixGroup)(gidNumber=".$this->gidNumber."))",array("cn"));
784       if($ldap->count()){
785         $cns = "";
786         while($attrs = $ldap->fetch()){
787           $cns .= $attrs['cn'][0].", ";
788         }
789         $cns = rtrim($cns,", ");
790         msg_dialog::display(_("Warning"),sprintf(_("The gidNumber '%s' is already in use by %s!"),$this->gidNumber,$cns) , WARNING_DIALOG );
791       }
792     }
794     /* Write back to ldap */
795     $ldap->cd($this->dn);
796     $this->cleanup();
797     $ldap->$mode($this->attrs);
799     /* Remove ACL dependencies too,
800      */
801     if($this->dn != $this->orig_dn && $this->orig_dn != "new"){
802       $tmp = new acl($this->config,$this->parent,$this->dn);
803       $tmp->update_acl_membership($this->orig_dn,$this->dn);
804     }
806     if($this->initially_was_account){
807       new log("modify","groups/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
808     }else{
809       new log("create","groups/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
810     }
812     $ret= 0;
813     if (!$ldap->success()){
814       msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, 0, get_class()));
815       $ret= 1;
816     }
818     /* Remove uid lock */
819     del_lock ("gidnumber");
821     /* Post that we've done*/
822     $this->handle_post_events($mode);
824     return ($ret);
825   }
827   function check()
828   {
829     /* Call common method to give check the hook */
830     $message= plugin::check();
832     /* Permissions for that base? */
833     if ($this->base != ""){
834       $new_dn= 'cn='.$this->cn.','.get_groups_ou().$this->base;
835     } else {
836       $new_dn= $this->dn;
837     }
839     /* must: cn */
840     if ($this->cn == "" && $this->acl_is_writeable("cn")){
841       $message[]= msgPool::required(_("Name"));
842     }
844     // Check if a wrong base was supplied
845     if(!$this->baseSelector->checkLastBaseUpdate()){
846       $message[]= msgPool::check_base();;
847     }
849     /* Check for valid input */
850     if (!tests::is_uid($this->cn)){
851       if (strict_uid_mode()){
852         $message[]= msgPool::invalid(_("Name"), $this->cn, "/[a-z0-9_-]/");
853       } else {
854         $message[]= msgPool::invalid(_("Name"), $this->cn, "/[a-z0-9_-]/i");
855       }
856     }
858     // Check if a wrong base was supplied
859     if(!$this->baseSelector->checkLastBaseUpdate()){
860       $message[]= msgPool::check_base();;
861     }
863     if($this->allowGroupsWithSameNameInOtherSubtrees == true){
865       /* Check for used 'cn' */
866       $ldap= $this->config->get_ldap_link();
867       if(($this->cn  != $this->orig_cn) || ($this->orig_dn == "new")){
868         $ldap->cd(get_groups_ou().$this->base);
869         $ldap->ls("(&(|(objectClass=gosaGroupOfNames)(objectClass=posixGroup))(cn=$this->cn))",get_groups_ou().$this->base,array("cn"));
870         if ($ldap->count() != 0){
871           $message[]= msgPool::duplicated(_("Name"));
872         }
873       }
875     }else{
877       /* Check for used 'cn' */
878       $ldap= $this->config->get_ldap_link();
879       $ldap->cd($this->config->current['BASE']);
880       $ldap->search("(&(|(objectClass=gosaGroupOfNames)(objectClass=posixGroup))(cn=$this->cn))",array("cn"));
881       if ($ldap->count() != 0){
883         /* New entry? */
884         if ($this->dn == 'new'){
885           $message[]= msgPool::duplicated(_("Name"));
886         }
888         /* Moved? */
889         elseif ($new_dn != $this->orig_dn){
890           $ldap->fetch();
891           if ($ldap->getDN() != $this->orig_dn){
892             $message[]= msgPool::duplicated(_("Name"));
893           }
894         }
895       }
896     }
897      
898     /* Check ID */
899     if ($this->force_gid == "1"){
900       if (!tests::is_id($this->gidNumber)){
901         $message[]= msgPool::invalid(_("GID"), $this->gidNumber, "/[0-9]/");
902       } else {
903         if ($this->gidNumber < $this->config->get_cfg_value("minId")){
904           $message[]= msgPool::toosmall(_("GID"), $this->config->get_cfg_value("minId"));
905         }
907       }
908     }
909     
910     /* Check if we are allowed to create or move this object 
911      */
912     if(!$this->orig_dn == "new" || 
913         $this->orig_base != $this->base || 
914         $this->cn != $this->orig_cn){
916       if($this->orig_dn == "new" && !$this->acl_is_createable($this->base)){
917         $message[] = msgPool::permCreate();
918       }elseif($this->orig_dn != "new" && !$this->acl_is_moveable($this->base)){
919         $message[] = msgPool::permMove();
920       }
921     }
923     return ($message);
924   }
927   function getCopyDialog()
928   {
929     $vars = array("cn");
930   
931     if($this ->force_gid){
932       $used = " checked ";
933       $dis  = "";
934     }else{
935       $used = "";
936       $dis  = " disabled ";
937     }
939     $smarty = get_smarty();
940     $smarty->assign("used",$used);
941     $smarty->assign("dis" ,$dis);
942     $smarty->assign("cn" ,$this->cn);
943     $smarty->assign("gidNumber",$this->gidNumber);
944     $str = $smarty->fetch(get_template_path("paste_generic.tpl",TRUE));
945     $ret = array();
946     $ret['string'] = $str;
947     $ret['status'] = "";
948     return($ret);
949   }
951   function saveCopyDialog()
952   {
953     if(isset($_POST['cn'])){
954       $this->cn = $_POST['cn'];
955     }
956     if(isset($_POST['force_gid'])){
957       $this->force_gid  = 1;
958       $this->gidNumber= $_POST['gidNumber'];
959     }else{
960       $this->force_gid  = 0;
961       $this->gidNumber  = false;
962     }
963   }
965   
966   /* Return plugin informations for acl handling  */ 
967   static function plInfo()
968   {
969     return (array(  
970           "plShortName" => _("Generic"),
971           "plDescription" => _("Generic group settings"),
972           "plSelfModify"  => FALSE,
973           "plDepends"     => array(),
974           "plPriority"    => 0,
975           "plSection"     => array("administration"),
976           "plCategory"    => array("groups" => array("objectClass" => "posixGroup", "description" => _("Groups"))),
978           "plProvidedAcls"    => array(
979             "cn"                => _("Name"),
980             "description"       => _("Description"),
981             "base"              => _("Base"),
983             "gidNumber"         => _("GID"),
985             "sambaGroupType"    => _("Samba group type"),
986             "sambaDomainName"   => _("Samba domain name"),
987             "accessTo"        => _("System trust"),
988             "fonGroup"          => _("Phone pickup group"),
989             "nagiosGroup"       => _("Nagios group"),
991             "memberUid"         => _("Group member"))
992         ));
993   }
996   function multiple_save_object()
997   {
998     if(isset($_POST['group_mulitple_edit'])){
1000       /* Create a base backup and reset the
1001          base directly after calling plugin::save_object();
1002          Base will be set seperatly a few lines below */
1003       $base_tmp = $this->base;
1004       plugin::multiple_save_object();
1005       plugin::save_object();
1006       $this->trustModeDialog->multiple_save_object();
1007       $this->base = $base_tmp;
1009       foreach(array("base","smbgroup","groupType","sambaDomainName","fon_group","nagios_group") as $attr){
1010         if(isset($_POST['use_'.$attr])){
1011           $this->multi_boxes[] = $attr;
1012         }
1013       }
1015       /* Refresh base */
1016       if ($this->acl_is_moveable($this->base)){
1017         if (!$this->baseSelector->update()) {
1018           msg_dialog::display(_("Error"), msgPool::permMove(), ERROR_DIALOG);
1019         }
1020         if ($this->base != $this->baseSelector->getBase()) {
1021           $this->base= $this->baseSelector->getBase();
1022           $this->is_modified= TRUE;
1023         }
1024       }
1026       foreach (array( "smbgroup"   => "sambaGroupType" ,"nagios_group" => "nagios_group") as $val => $aclname) {
1027         if ($this->acl_is_writeable($aclname)){
1028           if(isset($_POST["$val"])){
1029             $this->$val=  TRUE;
1030           }else{
1031             $this->$val=  FALSE;
1032           }
1033         }
1034       }
1036       /* Save sambaDomain attribute */
1037       if ($this->acl_is_writeable("sambaDomainName") && isset ($_POST['sambaDomainName'])){
1038         $this->sambaDomainName= $_POST['sambaDomainName'];
1039         $this->groupType= $_POST['groupType'];
1040       }
1042       /* Save fon attribute */
1043       if ($this->acl_is_writeable("fonGroup")){
1044         if (isset ($_POST['fon_group'])){
1045           $this->fon_group= TRUE;
1046         } else {
1047           $this->fon_group= FALSE;
1048         }
1049       }
1050     }
1051   }
1054   function get_multi_edit_values()
1055   {
1056     $ret = plugin::get_multi_edit_values();
1057     $ret = array_merge($ret,$this->trustModeDialog->get_multi_edit_values());
1059     foreach(array("base","smbgroup","groupType","sambaDomainName","fon_group","nagios_group") as $attr){    
1060       if(in_array($attr,$this->multi_boxes)){
1061         $ret[$attr] = $this->$attr;
1062       }
1063     }
1065     $ret['memberUid'] = $this->memberUid;
1066     $ret['memberUid_used_by_some'] = $this->memberUid_used_by_some;
1067     return($ret);
1068   }
1070   function multiple_execute()
1071   {
1072     return($this->execute());
1073   }
1076   /* Initialize plugin with given atribute arrays
1077    */
1078   function init_multiple_support($attrs,$all)
1079   {
1080     plugin::init_multiple_support($attrs,$all);
1081     $this->trustModeDialog->init_multiple_support($attrs,$all);
1083     $this->memberUid = array();
1084     $this->memberUid_used_by_some = array();
1085     if (isset($attrs['memberUid'])){
1086       for ($i= 0; $i<$attrs['memberUid']['count']; $i++){
1087         $this->memberUid[$attrs['memberUid'][$i]]= $attrs['memberUid'][$i];
1088       }
1089       ksort($this->memberUid);
1090     }
1092     if (isset($all['memberUid'])){
1093       for ($i= 0; $i<$all['memberUid']['count']; $i++){
1094         if(!in_array($all['memberUid'][$i],$this->memberUid)){
1095           $this->memberUid_used_by_some[$all['memberUid'][$i]]= $all['memberUid'][$i];
1096         }
1097       }
1098       ksort($this->memberUid_used_by_some);
1099     }
1100   }
1103   function PrepareForCopyPaste($source)
1104   {
1105     plugin::PrepareForCopyPaste($source);
1107     $this->trustModeDialog->PrepareForCopyPaste($source);
1109     if ($this->smbgroup) { 
1110       $this->sambaSID = $this->getSambaSID(); 
1111     } 
1113     $this->memberUid = array();
1114     if(isset($source['memberUid'])){
1115       for($i = 0 ; $i < $source['memberUid']['count']; $i ++){
1116         $this->memberUid[] = $source['memberUid'][$i];
1117       }
1118     }
1119   }
1122   function set_acl_base($base)
1123   {
1124     plugin::set_acl_base($base);
1125     $this->trustModeDialog->set_acl_base($base);
1126   }
1129   /*! \brief  Enables multiple support for this plugin
1130    */
1131   function enable_multiple_support()
1132   {
1133     plugin::enable_multiple_support();
1134     $this->trustModeDialog->enable_multiple_support();
1135   }
1138   function set_multi_edit_values($attrs)
1139   {
1140     $users = array();
1142     /* Update groupMembership, keep optinal group */
1143     foreach($attrs['memberUid_used_by_some'] as $uid){
1144       if(in_array($uid,$this->memberUid)){
1145         $users[$uid] = $uid;
1146       }
1147     }
1149     /* Update groupMembership, add forced groups */
1150     foreach($attrs['memberUid'] as $uid){
1151       $users[$uid] = $uid;
1152     }
1153     plugin::set_multi_edit_values($attrs);
1154     $this->trustModeDialog->set_multi_edit_values($attrs);
1155     $this->memberUid = $users;
1156   }
1159   /*! \brief Get a new SambaSID for a group */ 
1160   function getSambaSID() 
1161   { 
1162     $ldap = $this->config->get_ldap_link(); 
1163     $gidNumber= $this->gidNumber; 
1164     while(TRUE){ 
1165       $sid= $this->SID."-".($gidNumber*2 + $this->ridBase+1); 
1166       $ldap->cd($this->config->current['BASE']); 
1167       $ldap->search("(sambaSID=$sid)",array("sambaSID")); 
1168       if ($ldap->count() == 0){ 
1169         break; 
1170       } 
1171       $gidNumber++; 
1172     } 
1173   
1174     return $sid; 
1175   } 
1178 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1179 ?>