Code

Removed jpgraph | qpl license doesn't match our needs
[gosa.git] / gosa-core / include / class_acl.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 /*! \brief ACL management plugin */ 
24 class acl extends plugin
25 {
26     /* Definitions */
27     var $plHeadline= "Access control";
28     var $plDescription= "Manage access control lists";
30     /* attribute list for save action */
31     var $attributes= array('gosaAclEntry');
32     var $objectclasses= array('gosaAcl');
34     /* Helpers */
35     var $dialogState= "head";
36     var $gosaAclEntry= array();
37     var $aclType= "";
38     var $aclObject= "";
39     var $aclContents= array();
40     var $target= "group";
41     var $aclTypes= array();
42     var $aclObjects= array();
43     var $aclFilter= "";
44     var $aclMyObjects= array();
45     var $users= array();
46     var $roles= array();
47     var $groups= array();
48     var $recipients= array();
49     var $isContainer= FALSE;
50     var $currentIndex= 0;
51     var $wasNewEntry= FALSE;
52     var $ocMapping= array();
53     var $savedAclContents= array();
54     var $myAclObjects = array();
55     var $acl_category = "acl/";
57     var $list =NULL;
59     var $sectionList = NULL;
60     var $roleList = NULL;
62     function acl (&$config, $parent, $dn= NULL)
63     {
64         /* Include config object */
65         plugin::plugin($config, $dn);
67         /* Load ACL's */
68         $this->gosaAclEntry= array();
69         if (isset($this->attrs['gosaAclEntry'])){
70             for ($i= 0; $i<$this->attrs['gosaAclEntry']['count']; $i++){
71                 $acl= $this->attrs['gosaAclEntry'][$i];
72                 $this->gosaAclEntry= array_merge($this->gosaAclEntry, acl::explodeACL($acl));
73             }
74         }
75         ksort($this->gosaAclEntry);
77         /* Save parent - we've to know more about it than other plugins... */
78         $this->parent= &$parent;
80         /* Container? */
81         if (preg_match('/^(o|ou|c|l|dc)=/i', $dn)){
82             $this->isContainer= TRUE;
83         }
85         /* Users */
86         $ui= get_userinfo();
87         $tag= $ui->gosaUnitTag;
88         $ldap= $config->get_ldap_link();
89         $ldap->cd($config->current['BASE']);
90         if ($tag == ""){
91             $ldap->search('(objectClass=gosaAccount)', array('uid', 'cn'));
92         } else {
93             $ldap->search('(&(objectClass=gosaAccount)(gosaUnitTag='.$tag.'))', array('uid', 'cn'));
94         }
95         while ($attrs= $ldap->fetch()){
97             // Allow objects without cn to be listed without causing an error.
98             if(!isset($attrs['cn'][0]) && isset($attrs['uid'][0])){
99                 $this->users['U:'.$attrs['dn']]=  $attrs['uid'][0];
100             }elseif(!isset($attrs['uid'][0]) && isset($attrs['cn'][0])){
101                 $this->users['U:'.$attrs['dn']]=  $attrs['cn'][0];
102             }elseif(!isset($attrs['uid'][0]) && !isset($attrs['cn'][0])){
103                 $this->users['U:'.$attrs['dn']]= $attrs['dn'];
104             }else{
105                 $this->users['U:'.$attrs['dn']]= $attrs['cn'][0].' ['.$attrs['uid'][0].']';
106             }
108         }
109         ksort($this->users);
111         /* Groups */
112         $ldap->cd($config->current['BASE']);
113 #    if ($tag == ""){
114     $ldap->search('(objectClass=posixGroup)', array('cn', 'description'));
115 #    } else {
116 #      $ldap->search('(&(objectClass=posixGroup)(gosaUnitTag='.$tag.'))', array('cn', 'description'));
117 #    }
118     while ($attrs= $ldap->fetch()){
119         $dsc= "";
120         if (isset($attrs['description'][0])){
121             $dsc= $attrs['description'][0];
122         }
123         $this->groups['G:'.$attrs['dn']]= $attrs['cn'][0].' ['.$dsc.']';
124     }
125     $this->groups['G:*']= _("All users");
126     ksort($this->groups);
128     /* Roles */
129     $ldap->cd($config->current['BASE']);
130 #    if ($tag == ""){
131     $ldap->search('(objectClass=gosaRole)', array('cn', 'description','gosaAclTemplate','dn'));
132 #    } else {
133 #     $ldap->search('(&(objectClass=gosaRole)(gosaUnitTag='.$tag.'))', array('cn', 'description','gosaAclTemplate','dn'));
134 #    }
135     while ($attrs= $ldap->fetch()){
136         $dsc= "";
137         if (isset($attrs['description'][0])){
138             $dsc= $attrs['description'][0];
139         }
141         $role_id = $attrs['dn'];
143         $this->roles[$role_id]['acls'] =array();
144         for ($i= 0; $i < $attrs['gosaAclTemplate']['count']; $i++){
145             $acl= $attrs['gosaAclTemplate'][$i];
146             $this->roles[$role_id]['acls'] = array_merge($this->roles[$role_id]['acls'],acl::explodeACL($acl));
147         }
148         $this->roles[$role_id]['description'] = $dsc;
149         $this->roles[$role_id]['cn'] = $attrs['cn'][0];
150     }
152     /* Objects */
153     $tmp= session::global_get('plist');
154     $plist= $tmp->info;
155     $cats = array();
156     if (isset($this->parent) && $this->parent !== NULL){
157         $oc= array();
158         foreach ($this->parent->by_object as $key => $obj){
159             $oc= array_merge($oc, $obj->objectclasses);
160             if(isset($obj->acl_category)){
161                 $tmp= str_replace("/","",$obj->acl_category);
162                 $cats[$tmp] = $tmp;
163             }
164         }
165         if (in_array_ics('organizationalUnit', $oc)){
166             $this->isContainer= TRUE;
167         }
168     } else {
169         $oc=  $this->attrs['objectClass'];
170     }
172     /* Extract available categories from plugin info list */
173     foreach ($plist as $class => $acls){
175         /* Only feed categories */
176         if (isset($acls['plCategory'])){
178             /* Walk through supplied list and feed only translated categories */
179             foreach($acls['plCategory'] as $idx => $data){
181                 /* Non numeric index means -> base object containing more informations */
182                 if (preg_match('/^[0-9]+$/', $idx)){
184                     if (!isset($this->ocMapping[$data])){
185                         $this->ocMapping[$data]= array();
186                         $this->ocMapping[$data][]= '0';
187                     }
189                     if(isset($cats[$data])){
190                         $this->myAclObjects[$data.'/'.$class]= $acls['plDescription'];
191                     }
192                     $this->ocMapping[$data][]= $class;
193                 } else {
194                     if (!isset($this->ocMapping[$idx])){
195                         $this->ocMapping[$idx]= array();
196                         $this->ocMapping[$idx][]= '0';
197                     }
198                     $this->ocMapping[$idx][]= $class;
199                     $this->aclObjects[$idx]= $data['description'];
201                     /* Additionally filter the classes we're interested in in "self edit" mode */
202                     if(!isset($data['objectClass'])) continue;
203                     if (is_array($data['objectClass'])){
204                         foreach($data['objectClass'] as $objectClass){
205                             if (in_array_ics($objectClass, $oc)){
206                                 $this->myAclObjects[$idx.'/'.$class]= $acls['plDescription'];
207                                 break;
208                             }
209                         }
210                     } else {
211                         if (in_array_ics($data['objectClass'], $oc)){
212                             $this->myAclObjects[$idx.'/'.$class]= $acls['plDescription'];
213                         }
214                     }
215                 }
217             }
218         }
219     }
221     /* Sort categories */
222     asort($this->aclObjects);
224     /* Fill acl types */
225     if ($this->isContainer){
226         $this->aclTypes= array("reset" => _("Reset ACLs"),
227                 "one" => _("One level"),
228                 "base" => _("Current object"),
229                 "sub" => _("Complete subtree"),
230                 "psub" => _("Complete subtree (permanent)"),
231                 "role" => _("Use ACL defined in role"));
232     } else {
233         $this->aclTypes= array("base" => _("Current object"),
234                 "role" => _("Use ACL defined in role"));
235     }
236     asort($this->aclTypes);
237     $this->targets= array("user" => _("Users"), "group" => _("Groups"));
238     asort($this->targets);
240     /* Finally - we want to get saved... */
241     $this->is_account= TRUE;
243     $this->updateList();
245     // Prepare lists 
246     $this->sectionList = new sortableListing();
247     $this->sectionList->setDeleteable(false);
248     $this->sectionList->setEditable(false);
249     $this->sectionList->setWidth("100%");
250     $this->sectionList->setHeight("120px");
251     $this->sectionList->setColspecs(array('200px','*'));
252     $this->sectionList->setHeader(array(_("Section"),_("Description")));
253     $this->sectionList->setDefaultSortColumn(1);
254     $this->sectionList->setAcl('rwcdm'); // All ACLs, we filter on our own here.
256     $this->roleList = new sortableListing();
257     $this->roleList->setDeleteable(false);
258     $this->roleList->setEditable(false);
259     $this->roleList->setWidth("100%");
260     $this->roleList->setHeight("120px");
261     $this->roleList->setColspecs(array('20px','*','*'));
262     $this->roleList->setHeader(array(_("Used"),_("Name"),_("Description")));
263     $this->roleList->setDefaultSortColumn(1);
264     $this->roleList->setAcl('rwcdm'); // All ACLs, we filter on our own here.
265     }
268     function updateList()
269     {
270         if(!$this->list){ 
271             $this->list = new sortableListing($this->gosaAclEntry,array(),TRUE);
272             $this->list->setDeleteable(true);
273             $this->list->setEditable(true);
274             $this->list->setColspecs(array('*'));
275             $this->list->setWidth("100%");
276             $this->list->setHeight("400px");
277             $this->list->setAcl("rwcdm");
278             $this->list->setHeader(array(_("Member"),_("Permissions"),_("Type")));
279         }
282         // Add ACL entries to the listing 
283         $lData = array();
284         foreach($this->gosaAclEntry as $id => $entry){
285             $lData[] = $this->convertForListing($entry);
286         }    
287         $this->list->setListData($this->gosaAclEntry, $lData);
288     }
291     function convertForListing($entry)
292     {
293         $member = implode($entry['members'],", ");
294         if(isset($entry['acl']) && is_array($entry['acl'])){
295             $acl = implode(array_keys($entry['acl']),", ");
296         }else{
297             $acl="";
298         }
299         return(array('data' => array($member, $acl, $this->aclTypes[$entry['type']])));
300     }
304     function execute()
305     {
306         /* Call parent execute */
307         plugin::execute();
309         $tmp= session::global_get('plist');
310         $plist= $tmp->info;
312         /* Handle posts */
313         if (isset($_POST['new_acl'])){
314             $this->dialogState= 'create';
315             $this->dialog= TRUE;
316             $this->currentIndex= count($this->gosaAclEntry);
317             $this->loadAclEntry(TRUE);
318         }
320         $new_acl= array();
321         $aclDialog= FALSE;
322         $firstedit= FALSE;
324         // Get listing actions. Delete or Edit.
325         $this->list->save_object();
326         $lAction = $this->list->getAction();
327         $this->gosaAclEntry = array_values($this->list->getMaintainedData());
329         /* Act on HTML post and gets here.
330          */
331         if($lAction['action'] == "edit"){
332             $this->currentIndex = $this->list->getKey($lAction['targets'][0]);
333             $this->dialogState= 'create';
334             $firstedit= TRUE;
335             $this->dialog= TRUE;
336             $this->loadAclEntry();
337         }
339         foreach($_POST as $name => $post){
341             $post =get_post($name);
343             /* Actions... */
344             if (preg_match('/^acl_edit_[0-9]*$/', $name)){
345                 $this->dialogState= 'create';
346                 $firstedit= TRUE;
347                 $this->dialog= TRUE;
348                 $this->currentIndex= preg_replace('/^acl_edit_([0-9]*)$/', '\1', $name);
349                 $this->loadAclEntry();
350                 continue;
351             }
353             if (preg_match('/^cat_edit_.*$/', $name)){
354                 $this->aclObject= preg_replace('/^cat_edit_(.*)$/', '\1', $name);
355                 $this->dialogState= 'edit';
356                 foreach ($this->ocMapping[$this->aclObject] as $oc){
357                     if (isset($this->aclContents[$oc])){
358                         $this->savedAclContents[$oc]= $this->aclContents[$oc];
359                     }
360                 }
361                 continue;
362             }
364             /* Only handle posts, if we allowed to modify ACLs */
365             if(!$this->acl_is_writeable("")){
366                 continue;
367             }
369             if (preg_match('/^acl_del_[0-9]*$/', $name)){
370                 unset($this->gosaAclEntry[preg_replace('/^acl_del_([0-9]*)$/', '\1', $name)]);
371                 continue;
372             }
374             if (preg_match('/^cat_del_.*$/', $name)){
375                 $idx= preg_replace('/^cat_del_(.*)$/', '\1', $name);
376                 foreach ($this->ocMapping[$idx] as $key){
377                     if(isset($this->aclContents[$idx]))
378                         unset($this->aclContents[$idx]);
379                     if(isset($this->aclContents["$idx/$key"]))
380                         unset($this->aclContents["$idx/$key"]);
381                 }
382                 continue;
383             }
385             /* ACL saving... */
386             if (preg_match('/^acl_.*_[^xy]$/', $name)){
387                 list($dummy, $object, $attribute, $value)= explode('_', $name);
389                 /* Skip for detection entry */
390                 if ($object == 'dummy') {
391                     continue;
392                 }
394                 /* Ordinary ACLs */
395                 if (!isset($new_acl[$object])){
396                     $new_acl[$object]= array();
397                 }
398                 if (isset($new_acl[$object][$attribute])){
399                     $new_acl[$object][$attribute].= $value;
400                 } else {
401                     $new_acl[$object][$attribute]= $value;
402                 }
403             }
405             // Remember the selected ACL role.
406             if(isset($_POST['selected_role']) && $_POST['aclType'] == 'role'){
407                 $this->aclContents = "";
408                 $this->aclContents = base64_decode(get_post('selected_role'));
409             }else{
410                 if(is_string($this->aclContents))
411                     $this->aclContents = array();
412             }
413         }
415         if(isset($_POST['acl_dummy_0_0_0'])){
416             $aclDialog= TRUE;
417         }
419         if($this->acl_is_writeable("")){
421             /* Only be interested in new acl's, if we're in the right _POST place */
422             if ($aclDialog && $this->aclObject != "" && is_array($this->ocMapping[$this->aclObject])){
424                 foreach ($this->ocMapping[$this->aclObject] as $oc){
426                     if(isset($this->aclContents[$oc]) && is_array($this->aclContents)){
427                         unset($this->aclContents[$oc]);
428                     }elseif(isset($this->aclContents[$this->aclObject.'/'.$oc]) && is_array($this->aclContents)){
429                         unset($this->aclContents[$this->aclObject.'/'.$oc]);
430                     }else{
431 #          trigger_error("Huhm?");
432                     }
433                     if (isset($new_acl[$oc]) && is_array($new_acl)){
434                         $this->aclContents[$oc]= $new_acl[$oc];
435                     }
436                     if (isset($new_acl[$this->aclObject.'/'.$oc]) && is_array($new_acl)){
437                         $this->aclContents[$this->aclObject.'/'.$oc]= $new_acl[$this->aclObject.'/'.$oc];
438                     }
439                 }
440             }
442             /* Save new acl in case of base edit mode */
443             if ($this->aclType == 'base' && !$firstedit){
444                 $this->aclContents= $new_acl;
445             }
446         }
448         /* Cancel new acl? */
449         if (isset($_POST['cancel_new_acl'])){
450             $this->dialogState= 'head';
451             $this->dialog= FALSE;
452             if ($this->wasNewEntry){
453                 unset ($this->gosaAclEntry[$this->currentIndex]);
454             }
455         }
457         /* Save common values */
458         if($this->acl_is_writeable("")){
459             foreach (array("aclType","aclFilter", "aclObject", "target") as $key){
460                 if (isset($_POST[$key])){
461                     $this->$key= get_post($key);
462                 }
463             }
464         }
466         /* Store ACL in main object? */
467         if (isset($_POST['submit_new_acl'])){
468             $this->gosaAclEntry[$this->currentIndex]['type']= $this->aclType;
469             $this->gosaAclEntry[$this->currentIndex]['members']= $this->recipients;
470             $this->gosaAclEntry[$this->currentIndex]['acl']= $this->aclContents;
471             $this->gosaAclEntry[$this->currentIndex]['filter']= $this->aclFilter;
472             $this->dialogState= 'head';
473             $this->dialog= FALSE;
474         }
476         /* Cancel edit acl? */
477         if (isset($_POST['cancel_edit_acl'])){
478             $this->dialogState= 'create';
479             foreach ($this->ocMapping[$this->aclObject] as $oc){
480                 if (isset($this->savedAclContents[$oc])){
481                     $this->aclContents[$oc]= $this->savedAclContents[$oc];
482                 }
483             }
484         }
486         /* Save edit acl? */
487         if (isset($_POST['submit_edit_acl'])){
488             $this->dialogState= 'create';
489         }
491         /* Add acl? */
492         if (isset($_POST['add_acl']) && $_POST['aclObject'] != ""){
493             $this->dialogState= 'edit';
494             $this->savedAclContents= array();
495             foreach ($this->ocMapping[$this->aclObject] as $oc){
496                 if (isset($this->aclContents[$oc])){
497                     $this->savedAclContents[$oc]= $this->aclContents[$oc];
498                 }
499             }
500         }
502         /* Add to list? */
503         if (isset($_POST['add']) && isset($_POST['source'])){
504             foreach ($_POST['source'] as $key){
505                 if ($this->target == 'user'){
506                     $this->recipients[$key]= $this->users[$key];
507                 }
508                 if ($this->target == 'group'){
509                     $this->recipients[$key]= $this->groups[$key];
510                 }
511             }
512             ksort($this->recipients);
513         }
515         /* Remove from list? */
516         if (isset($_POST['del']) && isset($_POST['recipient'])){
517             foreach ($_POST['recipient'] as $key){
518                 unset($this->recipients[$key]);
519             }
520         }
522         /* Create templating instance */
523         $smarty= get_smarty();
525         $smarty->assign("acl_readable",$this->acl_is_readable(""));
526         if(!$this->acl_is_readable("")){
527             return ($smarty->fetch (get_template_path('acl.tpl')));
528         }
530         if ($this->dialogState == 'head'){
531             $this->updateList();
532             $smarty->assign("aclList", $this->list->render());
533         }
535         if ($this->dialogState == 'create'){
538             if($this->aclType != 'role'){
540                 // Create a map of all used sections, this allows us to simply hide the remove button 
541                 //  if no acl is configured for the given section 
542                 // e.g. ';all;department/country;users/user;
543                 $usedList = ";".implode(array_keys($this->aclContents),';').";";
545                 /* Add settings for all categories to the (permanent) list */
546                 $data = $lData = array();
547                 foreach ($this->aclObjects as $section => $dsc){
548                     $summary= "";
549                     foreach($this->ocMapping[$section] as $oc){
550                         if (isset($this->aclContents[$oc]) && 
551                                 count($this->aclContents[$oc]) && 
552                                 isset($this->aclContents[$oc][0]) &&
553                                 $this->aclContents[$oc][0] != ""){
555                             $summary.= "$oc, ";
556                             continue;
557                         }
558                         if (isset($this->aclContents["$section/$oc"]) && 
559                                 count($this->aclContents["$section/$oc"])){
560                             $summary.= "$oc, ";
561                             continue;
562                         }
563                         if (isset($this->aclContents[$oc]) && 
564                                 !isset($this->aclContents[$oc][0]) && 
565                                 count($this->aclContents[$oc])){
566                             $summary.= "$oc, ";
567                         }
568                     }
570                     /* Set summary... */
571                     if ($summary == ""){
572                         $summary= '<i>'._("No ACL settings for this category!").'</i>';
573                     } else {
574                         $summary= trim($summary,", ");
575                         $summary= " ".sprintf(_("ACLs for: %s"), $summary);
576                     }
578                     $actions ="";
579                     if($this->acl_is_readable("")){
580                         $actions.= image('images/lists/edit.png','cat_edit_'.$section, 
581                                 msgPool::editButton(_("category ACL")));
582                     }
583                     if($this->acl_is_removeable() && preg_match("/;".$section."(;|\/)/", $usedList)){
584                         $actions.= image('images/lists/trash.png','cat_del_'.$section, 
585                                 msgPool::delButton(_("category ACL")));
586                     }   
587                     $data[] = $section;
588                     $lData[] = array('data'=>array($dsc, $summary, $actions));
589                 }
590                 $this->sectionList->setListData($data,$lData);
591                 $this->sectionList->update();
592                 $smarty->assign("aclList", $this->sectionList->render());
593             }
595             $smarty->assign("aclType",     set_post($this->aclType));
596             $smarty->assign("aclFilter",   set_post($this->aclFilter));
597             $smarty->assign("aclTypes",    set_post($this->aclTypes));
598             $smarty->assign("target",      set_post($this->target));
599             $smarty->assign("targets",     set_post($this->targets));
601             /* Assign possible target types */
602             $smarty->assign("targets", $this->targets);
603             foreach ($this->attributes as $attr){
604                 $smarty->assign($attr, set_post($this->$attr));
605             }
608             /* Generate list */
609             $tmp= array();
610             if ($this->target == "group" && !isset($this->recipients["G:*"])){
611                 $tmp["G:*"]= _("All users");
612             }
613             foreach (array("user" => "users", "group" => "groups") as $field => $arr){
614                 if ($this->target == $field){
615                     foreach ($this->$arr as $key => $value){
616                         if (!isset($this->recipients[$key])){
617                             $tmp[$key]= $value;
618                         }
619                     }
620                 }
621             }
622             $smarty->assign('sources', set_post($tmp));
623             $smarty->assign('recipients', set_post($this->recipients));
625             /* Acl selector if scope is base */
626             if ($this->aclType == 'base'){
627                 $smarty->assign('aclSelector', $this->buildAclSelector($this->myAclObjects));
628             }
630             /* Role selector if scope is base */
631             if ($this->aclType == 'role'){
632                 $smarty->assign('roleSelector', $this->buildRoleSelector($this->roles));
633             }
634         }
636         if ($this->dialogState == 'edit'){
637             $smarty->assign('headline', sprintf(_("Edit ACL for '%s' with scope '%s'"), $this->aclObjects[$this->aclObject], $this->aclTypes[$this->aclType]));
639             /* Collect objects for selected category */
640             foreach ($this->ocMapping[$this->aclObject] as $idx => $class){
641                 if ($idx == 0){
642                     continue;
643                 }
644                 $aclObjects[$this->aclObject.'/'.$class]= $plist[$class]['plDescription'];
645             }
647             /* Role selector if scope is base */
648             if ($this->aclType == 'role'){
649                 $smarty->assign('roleSelector', $this->buildRoleSelector($this->roles));
650             } else {
651                 $smarty->assign('aclSelector', $this->buildAclSelector($aclObjects));
652             }
653         }
655         /* Show main page */
656         $smarty->assign("dialogState", $this->dialogState);
658         /* Assign acls */ 
659         $smarty->assign("acl_createable",$this->acl_is_createable());
660         $smarty->assign("acl_writeable" ,$this->acl_is_writeable(""));
661         $smarty->assign("acl_readable"  ,$this->acl_is_readable(""));
662         $smarty->assign("acl_removeable",$this->acl_is_removeable());
664         return ($smarty->fetch (get_template_path('acl.tpl')));
665     }
668     function sort_by_priority($list)
669     {
670         $tmp= session::global_get('plist');
671         $plist= $tmp->info;
672         asort($plist);
673         $newSort = array();
675         foreach($list as $name => $translation){
676             $na  =  preg_replace("/^.*\//","",$name);
677             $prio = 0;
678             if(isset($plist[$na]['plPriority'])){
679                 $prio=  $plist[$na]['plPriority'] ;
680             }
682             $newSort[$name] = $prio;
683         }
685         asort($newSort);
687         $ret = array();
688         foreach($newSort as $name => $prio){
689             $ret[$name] = $list[$name];
690         }
691         return($ret);
692     }
695     function buildRoleSelector($list)
696     {
697         $selected = $this->aclContents;
698         if(!is_string($this->aclContents) || !isset($list[$this->aclContents])){
699             $selected = key($list);
700         }
702         $data = $lData = array();
703         foreach($list as $dn => $values){
704             if($dn == $selected){    
705                 $option = "<input type='radio' name='selected_role' value='".base64_encode($dn)."' checked>";
706             }else{
707                 $option = "<input type='radio' name='selected_role' value='".base64_encode($dn)."'>";
708             }
709             $data[] = postEncode($dn);
710             $lData[] = array('data'=>array($option, $values['cn'], $values['description']));
711         }
712         $this->roleList->setListData($data,$lData);
713         $this->roleList->update();
714         return($this->roleList->render());
715     } 
718     function buildAclSelector($list)
719     {
720         $display= "<input type='hidden' name='acl_dummy_0_0_0' value='1'>";
721         $cols= 3;
722         $tmp= session::global_get('plist');
723         $plist= $tmp->info;
724         asort($plist);
726         /* Add select all/none buttons */
727         $style = "style='width:100px;'";
729         if($this->acl_is_writeable("")){
730             $display .= "<button type='button' ".$style." name='toggle_all_create' onClick=\"acl_toggle_all('_0_c$');\" >Toggle C</button>";
731             $display .= "<button type='button' ".$style." name='toggle_all_move'   onClick=\"acl_toggle_all('_0_m$');\" >Toggle M</button>";
732             $display .= "<button type='button' ".$style." name='toggle_all_remove' onClick=\"acl_toggle_all('_0_d$');\" >Toggle D</button> - ";
733             $display .= "<button type='button' ".$style." name='toggle_all_read'   onClick=\"acl_toggle_all('_0_r$');\" >Toggle R</button>";
734             $display .= "<button type='button' ".$style." name='toggle_all_write'  onClick=\"acl_toggle_all('_0_w$');\" >Toggle W</button> - ";
736             $display .= "<button type='button' ".$style." name='toggle_all_sub_read'  onClick=\"acl_toggle_all('[^0]_r$');\" >R+</button>";
737             $display .= "<button type='button' ".$style." name='toggle_all_sub_write'  onClick=\"acl_toggle_all('[^0]_w$');\" >W+</button>";
739             $display .= "<br>";
741             $style = "style='width:50px;'";
742             $display .= "<button type='button' ".$style." name='set_true_all_create' onClick=\"acl_set_all('_0_c$',true);\" >C+</button>";
743             $display .= "<button type='button' ".$style." name='set_false_all_create' onClick=\"acl_set_all('_0_c$',false);\" >C-</button>";
744             $display .= "<button type='button' ".$style." name='set_true_all_move' onClick=\"acl_set_all('_0_m$',true);\" >M+</button>";
745             $display .= "<button type='button' ".$style." name='set_false_all_move' onClick=\"acl_set_all('_0_m$',false);\" >M-</button>";
746             $display .= "<button type='button' ".$style." name='set_true_all_remove' onClick=\"acl_set_all('_0_d$',true);\" >D+</button>";
747             $display .= "<button type='button' ".$style." name='set_false_all_remove' onClick=\"acl_set_all('_0_d$',false);\" >D-</button> - ";
748             $display .= "<button type='button' ".$style." name='set_true_all_read' onClick=\"acl_set_all('_0_r$',true);\" >R+</button>";
749             $display .= "<button type='button' ".$style." name='set_false_all_read' onClick=\"acl_set_all('_0_r$',false);\" >R-</button>";
750             $display .= "<button type='button' ".$style." name='set_true_all_write' onClick=\"acl_set_all('_0_w$',true);\" >W+</button>";
751             $display .= "<button type='button' ".$style." name='set_false_all_write' onClick=\"acl_set_all('_0_w$',false);\" >W-</button> - ";
753             $display .= "<button type='button' ".$style." name='set_true_all_read' onClick=\"acl_set_all('[^0]_r$',true);\" >R+</button>";
754             $display .= "<button type='button' ".$style." name='set_false_all_read' onClick=\"acl_set_all('[^0]_r$',false);\" >R-</button>";
755             $display .= "<button type='button' ".$style." name='set_true_all_write' onClick=\"acl_set_all('[^0]_w$',true);\" >W+</button>";
756             $display .= "<button type='button' ".$style." name='set_false_all_write' onClick=\"acl_set_all('[^0]_w$',false);\" >W-</button>";
757         }
759         /* Build general objects */
760         $list =$this->sort_by_priority($list);
761         foreach ($list as $key => $name){
763             /* Create sub acl if it does not exist */
764             if (!isset($this->aclContents[$key])){
765                 $this->aclContents[$key]= array();
766             }
767             if(!isset($this->aclContents[$key][0])){
768                 $this->aclContents[$key][0]= '';
769             }
771             $currentAcl= $this->aclContents[$key];
773             /* Get the overall plugin acls 
774              */
775             $overall_acl ="";
776             if(isset($currentAcl[0])){
777                 $overall_acl = $currentAcl[0];
778             }
780             // Detect configured plugins
781             $expand = count($currentAcl) > 1 || $currentAcl[0] != "";
783             /* Object header */
784             $tname= preg_replace("/[^a-z0-9]/i","_",$name);
786             if($expand){
787                 $back_color = "#C8C8FF";
788             }else{
789                 $back_color = "#C8C8C8";
790             }
792             if(isset($_SERVER['HTTP_USER_AGENT']) && 
793                     (preg_match("/gecko/i",$_SERVER['HTTP_USER_AGENT'])) || 
794                     (preg_match("/presto/i",$_SERVER['HTTP_USER_AGENT']))) {
795                 $display.= "\n<table summary='{$name}' style='width:100%;border:1px solid #A0A0A0' cellspacing=0 cellpadding=2>".
796                     "\n  <tr>".
797                     "\n    <td style='background-color:{$back_color};height:1.8em;' colspan=".($cols-1)."><b>"._("Object").": $name</b></td>".
798                     "\n    <td align='right' style='background-color:{$back_color};height:1.8em;'>".
799                     "\n    <button type='button' onclick=\"$('{$tname}').toggle();\">"._("Show/hide advanced settings")."</button></td>".
800                     "\n  </tr>";
801             } else if (isset($_SERVER['HTTP_USER_AGENT']) && preg_match("/ie/i",$_SERVER['HTTP_USER_AGENT'])) {
802                 $display.= "\n<table summary='{$name}' style='width:100%;border:1px solid #A0A0A0' cellspacing=0 cellpadding=2>".
803                     "\n  <tr>".
804                     "\n    <td style='background-color:#C8C8C8;height:1.8em;' colspan=".($cols-1)."><b>"._("Object").": $name</b></td>".
805                     "\n    <td align='right' style='background-color:#C8C8C8;height:1.8em;'>".
806                     "\n    <button type='button' onclick=\"$('{$tname}').toggle();\">"._("Show/hide advanced settings")."</button></td>".
807                     "\n  </tr>";
808             } else {
809                 $display.= "\n<table summary='{$name}' style='width:100%;border:1px solid #A0A0A0' cellspacing=0 cellpadding=2>".
810                     "\n  <tr>".
811                     "\n    <td style='background-color:#C8C8C8;height:1.8em;' colspan=$cols><b>"._("Object").": $name</b></td>".
812                     "\n  </tr>";
813             }
815             /* Generate options */
816             $spc= "&nbsp;&nbsp;";
817             $options= $this->mkchkbx($key."_0_c",  _("Create objects"), preg_match('/c/', $overall_acl)).$spc;
818             $options.= $this->mkchkbx($key."_0_m", _("Move objects"), preg_match('/m/', $overall_acl)).$spc;
819             $options.= $this->mkchkbx($key."_0_d", _("Remove objects"), preg_match('/d/', $overall_acl)).$spc;
820             if ($plist[preg_replace('%^.*/%', '', $key)]['plSelfModify']){
821                 $options.= $this->mkchkbx($key."_0_s", _("Restrict changes to user's own object"), preg_match('/s/', $overall_acl)).$spc;
822             }
824             /* Global options */
825             $more_options= $this->mkchkbx($key."_0_r",  _("read"), preg_match('/r/', $overall_acl)).$spc;
826             $more_options.= $this->mkchkbx($key."_0_w", _("write"), preg_match('/w/', $overall_acl));
828             $display.= "\n  <tr>".
829                 "\n    <td style='background-color:#E0E0E0' colspan=".($cols-1).">$options</td>".
830                 "\n    <td style='background-color:#D4D4D4'>&nbsp;"._("Complete object").": $more_options</td>".
831                 "\n  </tr>";
833             /* Walk through the list of attributes */
834             $cnt= 1;
835             $splist= $plist[preg_replace('%^.*/%', '', $key)]['plProvidedAcls'];
836             if(session::global_get('js')) {
837                 if(isset($_SERVER['HTTP_USER_AGENT']) && 
838                         (preg_match("/gecko/i",$_SERVER['HTTP_USER_AGENT'])) || (preg_match("/presto/i",$_SERVER['HTTP_USER_AGENT']))) {
839                     $display.= "\n  <tr id='tr_$tname' style='vertical-align:top;height:0px;'>".
840                         "\n    <td colspan=".$cols.">".
841                         "\n      <div id='$tname' style='overflow:hidden; display:none;vertical-align:top;width:100%;'>".
842                         "\n        <table style='width:100%;' summary='{$name}'>";
843                 } else if (isset($_SERVER['HTTP_USER_AGENT']) && preg_match("/ie/i",$_SERVER['HTTP_USER_AGENT'])) {
844                     $display.= "\n  <tr id='tr_$tname' style='vertical-align:top;height:0px;'>".
845                         "\n    <td colspan=".$cols.">".
846                         "\n      <div id='$tname' style='position:absolute;overflow:hidden;display:none;;vertical-align:top;width:100%;'>".
847                         "\n        <table style='width:100%;' summary='{$name}'>";
848                 }else{
849                 }
850             }
853             foreach($splist as $attr => $dsc){
855                 /* Skip pl* attributes, they are internal... */
856                 if (preg_match('/^pl[A-Z]+.*$/', $attr)){
857                     continue;
858                 }
860                 /* Open table row */
861                 if ($cnt == 1){
862                     $display.= "\n  <tr>";
863                 }
865                 /* Close table row */
866                 if ($cnt == $cols){
867                     $cnt= 1;
868                     $rb= "";
869                     $end= "\n  </tr>";
870                 } else {
871                     $cnt++;
872                     $rb= "border-right:1px solid #A0A0A0;";
873                     $end= "";
874                 }
876                 /* Collect list of attributes */
877                 $state= "";
878                 if (isset($currentAcl[$attr])){
879                     $state= $currentAcl[$attr];
880                 }
881                 $display.= "\n    <td style='border-top:1px solid #A0A0A0;${rb}width:".(int)(100/$cols)."%'>".
882                     "\n      <b>$dsc</b> ($attr)<br>".$this->mkrwbx($key."_".$attr, $state)."</td>$end";
883             }
885             /* Fill missing td's if needed */
886             if (--$cnt != $cols && $cnt != 0){
887                 $display.= str_repeat("\n    <td style='border-top:1px solid #A0A0A0; width:".(int)(100/$cols)."%'>&nbsp;</td>", $cols-$cnt); 
888             }
890             if(session::global_get('js')) {
891                 if(isset($_SERVER['HTTP_USER_AGENT']) && 
892                         (preg_match("/gecko/i",$_SERVER['HTTP_USER_AGENT'])) || 
893                         (preg_match("/presto/i",$_SERVER['HTTP_USER_AGENT'])) || 
894                         (preg_match("/ie/i",$_SERVER['HTTP_USER_AGENT']))) {
895                     $display.= "\n        </table>".
896                         "\n      </div>".
897                         "\n    </td>".
898                         "\n  </tr>";
899                 }
900             }
902             $display.= "\n</table><br />\n";
903         }
905         return ($display);
906     }
909     function mkchkbx($name, $text, $state= FALSE)
910     {
911         $state= $state?"checked":"";
912         if($this->acl_is_writeable("")){
913             $tname= preg_replace("/[^a-z0-9]/i","_",$name);
914             return "\n      <input id='acl_$tname' type=checkbox name='acl_$name' $state>".
915                 "\n      <label for='acl_$tname'>$text</label>";
916         }else{
917             return "\n <input type='checkbox' disabled name='dummy_".microtime(1)."' $state>$text";
918         }
919     }
922     function mkrwbx($name, $state= "")
923     {
924         $rstate= preg_match('/r/', $state)?'checked':'';
925         $wstate= preg_match('/w/', $state)?'checked':'';
926         $tname= preg_replace("/[^a-z0-9]/i","_",$name);
928         if($this->acl_is_writeable("")){
929             return ("\n      <input id='acl_".$tname."_r' type=checkbox name='acl_${name}_r' $rstate>".
930                     "\n      <label for='acl_".$tname."_r'>"._("read")."</label>".
931                     "\n      <input id='acl_".$tname."_w' type=checkbox name='acl_${name}_w' $wstate>".
932                     "\n      <label for='acl_".$tname."_w'>"._("write")."</label>");
933         }else{
934             return ("\n      <input disabled type=checkbox name='dummy_".microtime(1)."' $rstate>"._("read").
935                     "\n      <input disabled type=checkbox name='dummy_".microtime(1)."' $wstate>"._("write"));
936         }
937     }
940     static function explodeACL($acl)
941     {
943         $list= explode(':', $acl);
944         if(count($list) == 5){
945             list($index, $type,$member,$permission,$filter)= $list;
946             $filter = base64_decode($filter);
947         }elseif(count($list) == 4){
948             $filter = "";
949             list($index, $type,$member,$permission)= $list;
950         }else{
951             $permission = "";
952             $filter = "";
953             list($index, $type,$member)= $list;
954         }
956         $a= array( $index => array("type" => $type,
957                     "filter"=> $filter,
958                     "members" => acl::extractMembers($acl,$type == "role")));
960         /* Handle different types */
961         switch ($type){
963             case 'psub':
964             case 'sub':
965             case 'one':
966             case 'base':
967                 $a[$index]['acl']= acl::extractACL($acl);
968                 break;
970             case 'role':
971                 $a[$index]['acl']= base64_decode(preg_replace('/^[^:]+:[^:]+:([^:]+).*$/', '\1', $acl));
972                 break;
974             case 'reset':
975                 break;
977             default:
978                 msg_dialog::display(_("Internal error"), sprintf(_("Unknown ACL type '%s'!"), $type), ERROR_DIALOG);
979                 $a= array();
980         }
981         return ($a);
982     }
985     static function extractMembers($acl,$role = FALSE)
986     {
987         global $config;
988         $a= array();
990         /* Rip acl off the string, seperate by ',' and place it in an array */
991         if($role){
992             $ms= preg_replace('/^[^:]+:[^:]+:[^:]+:([^:]+).*$/', '\1', $acl);
993         }else{
994             $ms= preg_replace('/^[^:]+:[^:]+:([^:]+).*$/', '\1', $acl);
995         }
996         if ($ms == $acl){
997             return $a;
998         }
999         $ma= explode(',', $ms);
1001         /* Decode dn's, fill with informations from LDAP */
1002         $ldap= $config->get_ldap_link();
1003         foreach ($ma as $memberdn){
1004             // Check for wildcard here
1005             $dn= base64_decode($memberdn);
1006             if ($dn != "*") {
1007                 $ldap->cat($dn, array('cn', 'objectClass', 'description', 'uid'));
1009                 /* Found entry... */
1010                 if ($ldap->count()){
1011                     $attrs= $ldap->fetch();
1012                     if (in_array_ics('gosaAccount', $attrs['objectClass'])){
1013                         $a['U:'.$dn]= $attrs['cn'][0]." [".$attrs['uid'][0]."]";
1014                     } else {
1015                         $a['G:'.$dn]= $attrs['cn'][0];
1016                         if (isset($attrs['description'][0])){
1017                             $a['G:'.$dn].= " [".$attrs['description'][0]."]";
1018                         }
1019                     }
1021                     /* ... or not */
1022                 } else {
1023                     $a['U:'.$dn]= sprintf(_("Unknown entry '%s'!"), $dn);
1024                 }
1026             } else {
1027                 $a['G:*']= sprintf(_("All users"));
1028             }
1029         }
1031         return ($a);
1032     }
1035     static function extractACL($acl)
1036     {
1037         /* Rip acl off the string, seperate by ',' and place it in an array */
1038         $as= preg_replace('/^[^:]+:[^:]+:[^:]*:([^:]*).*$/', '\1', $acl);
1039         $aa= explode(',', $as);
1040         $a= array();
1042         /* Dis-assemble single ACLs */
1043         foreach($aa as $sacl){
1045             /* Dis-assemble field ACLs */
1046             $ao= explode('#', $sacl);
1047             $gobject= "";
1048             foreach($ao as $idx => $ssacl){
1050                 /* First is department with global acl */
1051                 $object= preg_replace('/^([^;]+);.*$/', '\1', $ssacl);
1052                 $gacl=   preg_replace('/^[^;]+;(.*)$/', '\1', $ssacl);
1053                 if ($idx == 0){
1054                     /* Create hash for this object */
1055                     $gobject= $object;
1056                     $a[$gobject]= array();
1058                     /* Append ACL if set */
1059                     if ($gacl != ""){
1060                         $a[$gobject]= array($gacl);
1061                     }
1062                 } else {
1064                     /* All other entries get appended... */
1065                     list($field, $facl)= explode(';', $ssacl);
1066                     $a[$gobject][$field]= $facl;
1067                 }
1069             }
1070         }
1072         return ($a);
1073     }
1076     function assembleAclSummary($entry)
1077     {
1078         $summary= "";
1080         /* Summarize ACL */
1081         if (isset($entry['acl'])){
1082             $acl= "";
1084             if($entry['type'] == "role"){
1086                 if(isset($this->roles[$entry['acl']])){  
1087                     $summary.= sprintf(_("ACL role: %s"), $this->roles[$entry['acl']]['cn']);
1088                 }else{
1089                     $summary.= sprintf(_("ACL role: %s"), "<i>"._("unknown ACL role")."</i>");
1090                 }
1091             }else{
1092                 foreach ($entry['acl'] as $name => $object){
1093                     if (count($object)){
1094                         $acl.= "$name, ";
1095                     }
1096                 }
1097                 $summary.= sprintf(_("Contains settings for these objects: %s"), preg_replace('/, $/', '', $acl));
1098             }
1099         }
1102         /* Summarize members */
1103         if(!($this instanceOf aclrole)){
1104             if ($summary != ""){
1105                 $summary.= ", ";
1106             }
1107             if (count($entry['members'])){
1108                 $summary.= _("Members").": ";
1109                 foreach ($entry['members'] as $cn){
1110                     $cn= preg_replace('/ \[.*$/', '', $cn);
1111                     $summary.= $cn.", ";
1112                 }
1113             } else {
1114                 $summary.= "<font color='red'><i>"._("inactive")."&nbsp;-&nbsp;"._("No members")."</i></font>";
1115             }
1116         }
1117         return (preg_replace('/, $/', '', $summary));
1118     }
1121     function loadAclEntry($new= FALSE)
1122     {
1123         /* New entry gets presets... */
1124         if ($new){
1125             $this->aclType= 'base';
1126             $this->aclFilter= "";
1127             $this->recipients= array();
1128             $this->aclContents= array();
1129         } else {
1130             $acl= $this->gosaAclEntry[$this->currentIndex];
1131             $this->aclType= $acl['type'];
1132             $this->recipients= $acl['members'];
1133             $this->aclContents= (isset($acl['acl'])) ? $acl['acl'] :"";
1134             $this->aclFilter= $acl['filter'];
1135         }
1137         $this->wasNewEntry= $new;
1138     }
1141     function aclPostHandler()
1142     {
1143         if (isset($_POST['save_acl'])){
1144             $this->save();
1145             return TRUE;
1146         }
1148         return FALSE;
1149     }
1152     function PrepareForCopyPaste($source)
1153     {
1154         plugin::PrepareForCopyPaste($source);
1156         $dn = $source['dn'];
1157         $acl_c = new acl($this->config, $this->parent,$dn);
1158         $this->gosaAclEntry = $acl_c->gosaAclEntry;
1159     }
1162     function save()
1163     {
1164         /* Assemble ACL's */
1165         $tmp_acl= array();
1167         foreach ($this->gosaAclEntry as $prio => $entry){
1168             $final= "";
1169             $members= "";
1170             if (isset($entry['members'])){
1171                 foreach ($entry['members'] as $key => $dummy){
1172                     $members.= base64_encode(preg_replace('/^.:/', '', $key)).',';
1173                 }
1174             }
1176             if($entry['type'] != "role"){
1177                 $final= $prio.":".$entry['type'].":".preg_replace('/,$/', '', $members);
1178             }else{
1179                 $final= $prio.":".$entry['type'].":".base64_encode($entry['acl']).":".preg_replace('/,$/', '', $members);
1180             }
1182             /* ACL's if needed */
1183             $final.= ":";
1184             if ($entry['type'] != "reset" && $entry['type'] != "role"){
1185                 $acl = "";
1186                 if (isset($entry['acl'])){
1187                     foreach ($entry['acl'] as $object => $contents){
1189                         /* Only save, if we've some contents in there... */
1190                         if (count($contents)){
1191                             $acl.= $object.";";
1193                             foreach($contents as $attr => $permission){
1195                                 /* First entry? Its the one for global settings... */
1196                                 if ($attr == '0'){
1197                                     $acl.= $permission;
1198                                 } else {
1199                                     $acl.= '#'.$attr.';'.$permission;
1200                                 }
1202                             }
1203                             $acl.= ',';
1204                         }
1206                     }
1207                 }
1208                 $final.= preg_replace('/,$/', '', $acl);
1209             }
1211             /* Append additional filter options 
1212              */
1213             if(!empty($entry['filter'])){
1214                 $final .= ":".base64_encode($entry['filter']);
1215             }
1217             $tmp_acl[]= $final;
1218         }
1220         /* Call main method */
1221         plugin::save();
1223         /* Finally (re-)assign it... */
1224         $this->attrs['gosaAclEntry']= $tmp_acl;
1226         /* Remove acl from this entry if it is empty... */
1227         if (!count($tmp_acl)){
1228             /* Remove attribute */
1229             if ($this->initially_was_account){
1230                 $this->attrs['gosaAclEntry']= array();
1231             } else {
1232                 if (isset($this->attrs['gosaAclEntry'])){
1233                     unset($this->attrs['gosaAclEntry']);
1234                 }
1235             }
1237             /* Remove object class */
1238             $this->attrs['objectClass']= array_remove_entries(array('gosaAcl'), $this->attrs['objectClass']);
1239         }    
1241         /* Do LDAP modifications */
1242         $ldap= $this->config->get_ldap_link();
1243         $ldap->cd($this->dn);
1244         $this->cleanup();
1245         $ldap->modify ($this->attrs);
1247         if(count($this->attrs)){
1248             new log("modify","acls/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
1249         }
1251         if (!$ldap->success()){
1252             msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_MOD, get_class()), ERROR_DIALOG);
1253         }
1255         /* Refresh users ACLs */
1256         $ui= get_userinfo();
1257         $ui->loadACL();
1258         session::global_set('ui',$ui);
1259     }
1262     function remove_from_parent()
1263     {
1264         plugin::remove_from_parent();
1266         /* include global link_info */
1267         $ldap= $this->config->get_ldap_link();
1269         $ldap->cd($this->dn);
1270         $this->cleanup();
1271         $ldap->modify ($this->attrs);
1273         new log("remove","acls/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
1275         /* Optionally execute a command after we're done */
1276         $this->handle_post_events("remove",array("uid" => $this->uid));
1277     }
1280     /* Return plugin informations for acl handling */
1281     static function plInfo()
1282     {
1283         return (array(
1284                     "plShortName"   => _("ACL"),
1285                     "plDescription" => _("ACL")."&nbsp;("._("Access control list").")",
1286                     "plSelfModify"  => FALSE,
1287                     "plDepends"     => array(),
1288                     "plPriority"    => 0,
1289                     "plSection"     => array("administration"),
1290                     "plRequirements"=> array('ldapSchema' => array('gosaAcl' => '>=2.7')),
1291                     "plCategory"    => array("acl" => array("description"  => _("ACL")."&nbsp;&amp;&nbsp;"._("ACL roles"),
1292                             "objectClass"  => array("gosaAcl","gosaRole"))),
1293                     "plProvidedAcls"=> array(
1294                         "gosaAclEntry"          => _("ACL Entries")
1295                         )
1297                     ));
1298     }
1301     /* Remove acls defined for $src */
1302     function remove_acl()
1303     {
1304         acl::remove_acl_for($this->dn);
1305     }
1308     /* Remove acls defined for $src */
1309     static function remove_acl_for($dn)
1310     {                                  
1311         global $config;                  
1313         $ldap = $config->get_ldap_link();
1314         $ldap->cd($config->current['BASE']);
1315         $ldap->search("(&(objectClass=gosaAcl)(gosaAclEntry=*".base64_encode($dn)."*))",array("gosaAclEntry","dn"));
1316         $new_entries= array();                                                                                      
1317         while($attrs = $ldap->fetch()){                                                                             
1318             if (!isset($attrs['gosaAclEntry'])) {                                                                     
1319                 continue;                                                                                               
1320             }                                                                                                         
1321             unset($attrs['gosaAclEntry']['count']);                                                                   
1323             // Remove entry directly
1324             foreach($attrs['gosaAclEntry'] as $id => $entry){
1325                 $parts= explode(':',$entry);                     
1326                 $members= explode(',',$parts[2]);                
1327                 $new_members= array();                         
1328                 foreach($members as $member) {                 
1329                     if (base64_decode($member) != $dn) {         
1330                         $new_members[]= $member;                   
1331                     } else {                                     
1332                         gosa_log("modify","users/acl",$attrs['dn'],array(),sprintf("Removed acl for %s on object %s.",$dn,$attrs['dn']));
1333                     }                                                                                                                  
1334                 }                                                                                                                    
1336                 /* We can completely remove the entry if there are no members anymore */
1337                 if (count($new_members)) {                                              
1338                     $parts[2]= implode(",", $new_members);                                
1339                     $new_entries[]= implode(":", $parts);                                 
1340                 }                                                                       
1341             }                                                                         
1343             // There should be a modification, so write it back
1344             $ldap->cd($attrs['dn']);
1345             $new_attrs= array("gosaAclEntry" => $new_entries);
1346             $ldap->modify($new_attrs);
1347             if (!$ldap->success()){
1348                 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_MOD, get_class()), ERROR_DIALOG);
1349             }
1350         }
1351     }
1354     function update_acl_membership($src,$dst)
1355     {
1356         $ldap = $this->config->get_ldap_link();
1357         $ldap->cd($this->config->current['BASE']);
1358         $ldap->search("(&(objectClass=gosaAcl)(gosaAclEntry=*".base64_encode($src)."*))",array("gosaAclEntry","dn"));
1359         while($attrs = $ldap->fetch()){
1360             $acl = new acl($this->config,$this->parent,$attrs['dn']);
1361             foreach($acl->gosaAclEntry as $id => $entry){
1362                 foreach($entry['members'] as $m_id => $member){
1363                     if($m_id == "U:".$src){
1364                         unset($acl->gosaAclEntry[$id]['members'][$m_id]);
1365                         $new = "U:".$dst;
1366                         $acl->gosaAclEntry[$id]['members'][$new] = $new;
1367                         gosa_log("modify","users/acl",$attrs['dn'],array(),sprintf("Updated acl for user %s on object %s.",$src,$attrs['dn']));
1368                     }
1369                     if($m_id == "G:".$src){
1370                         unset($acl->gosaAclEntry[$id]['members'][$m_id]);
1371                         $new = "G:".$dst;
1372                         $acl->gosaAclEntry[$id]['members'][$new] = $new;
1373                         gosa_log("modify","groups/acl",$attrs['dn'],array(),sprintf("Updated acl for group %s on object %s.",$src,$attrs['dn']));
1374                     }
1375                 }
1376             }
1377             $acl -> save();
1378         }
1379     }
1382     // We are only interessted in our own acls ... 
1383     function set_acl_category($category)
1384     {
1385         plugin::set_acl_category("acl");
1386     }
1389 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1390 ?>