Code

Also allow 0 as release name
[gosa.git] / plugins / admin / acl / class_acl.inc
1 <?php
3 class acl extends plugin
4 {
5   /* Definitions */
6   var $plHeadline= "Access control";
7   var $plDescription= "This does something";
9   /* attribute list for save action */
10   var $attributes= array('gosaAclEntry');
11   var $objectclasses= array('gosaAcl');
13   /* Helpers */
14   var $dialogState= "head";
15   var $gosaAclEntry= array();
16   var $aclType= "";
17   var $aclObject= "";
18   var $aclContents= array();
19   var $target= "group";
20   var $aclTypes= array();
21   var $aclObjects= array();
22   var $aclMyObjects= array();
23   var $users= array();
24   var $groups= array();
25   var $recipients= array();
26   var $isContainer= FALSE;
27   var $currentIndex= 0;
28   var $wasNewEntry= FALSE;
29   var $ocMapping= array();
30   var $savedAclContents= array();
33   function acl ($config, $dn= NULL)
34   {
35     /* Include config object */
36     plugin::plugin($config, $dn);
38     /* Load ACL's */
39     $this->gosaAclEntry= array();
40     if (isset($this->attrs['gosaAclEntry'])){
41       for ($i= 0; $i<$this->attrs['gosaAclEntry']['count']; $i++){
42         $acl= $this->attrs['gosaAclEntry'][$i];
43         $this->gosaAclEntry= array_merge($this->gosaAclEntry, $this->explodeACL($acl));
44       }
45     }
46     ksort($this->gosaAclEntry);
48     /* Container? */
49     if (preg_match('/^(ou|c|l|dc)=/i', $dn)){
50       $this->isContainer= TRUE;
51     }
53     /* Fill acl types */
54     if ($this->isContainer){
55       $this->aclTypes= array("reset" => _("Reset ACLs"),
56                              "one" => _("One level"),
57                              "base" => _("Current object"),
58                              "sub" => _("Complete subtree"),
59                              "psub" => _("Complete subtree (permanent)"),
60                              "role" => _("Use ACL defined in role"));
61     } else {
62       $this->aclTypes= array("base" => _("Current object"),
63           "role" => _("Use ACL defined in role"));
64     }
65     asort($this->aclTypes);
66     $this->targets= array("user" => _("Users"), "group" => _("Groups"));
67     asort($this->targets);
69     /* Users */
70     $ui= get_userinfo();
71     $tag= $ui->gosaUnitTag;
72     $ldap= $config->get_ldap_link();
73     $ldap->cd($config->current['BASE']);
74     if ($tag == ""){
75       $ldap->search('(objectClass=gosaAccount)', array('uid', 'cn'));
76     } else {
77       $ldap->search('(&(objectClass=gosaAccount)(gosaUnitTag='.$tag.'))', array('uid', 'cn'));
78     }
79     while ($attrs= $ldap->fetch()){
80       $this->users['U:'.$attrs['dn']]= $attrs['cn'][0].' ['.$attrs['uid'][0].']';
81     }
82     ksort($this->users);
84     /* Groups */
85     $ldap->cd($config->current['BASE']);
86     if ($tag == ""){
87       $ldap->search('(objectClass=posixGroup)', array('cn', 'description'));
88     } else {
89       $ldap->search('(&(objectClass=posixGroup)(gosaUnitTag='.$tag.'))', array('cn', 'description'));
90     }
91     while ($attrs= $ldap->fetch()){
92       $dsc= "";
93       if (isset($attrs['description'][0])){
94         $dsc= $attrs['description'][0];
95       }
96       $this->groups['G:'.$attrs['dn']]= $attrs['cn'][0].' ['.$dsc.']';
97     }
98     ksort($this->groups);
100     /* Objects */
101     $tmp= get_global('plist');
102     $plist= $tmp->info;
103     foreach ($plist as $class => $acls){
104       if (isset($acls['plDescription'])){
105         /* Only feed categories */
106         if (isset($acls['plDepends']['description'])){
107           $this->aclObjects[$acls['plDepends']['objectClass']]= $acls['plDepends']['description'];
108         }
110         /* Additionally filter the classes we're interested in in "self edit" mode */
111         if (in_array_ics($acls['plDepends']['objectClass'], $this->attrs['objectClass'])){
112           $this->myAclObjects[$class]= $acls['plDescription'];
113         }
114       }
115     }
116     asort($this->aclObjects);
118     /* Generate mapping object */
119     foreach ($plist as $oc => $pl){
120       if (isset($pl['plDepends']['objectClass'])){
121         $class= $pl['plDepends']['objectClass'];
122         if (!isset($this->ocMapping[$class])){
123           $this->ocMapping[$class]= array();
124         }
125         $this->ocMapping[$class][]= $oc;
126       }
127     }
128   }
131   function execute()
132   {
133     /* Call parent execute */
134     plugin::execute();
136     $tmp= get_global('plist');
137     $plist= $tmp->info;
139     /* Handle posts */
140     if (isset($_POST['new_acl'])){
141       $this->dialogState= 'create';
142       $this->dialog= TRUE;
143       $this->currentIndex= count($this->gosaAclEntry);
144       $this->loadAclEntry(TRUE);
145     }
147     $new_acl= array();
148     $aclDialog= FALSE;
149     foreach($_POST as $name => $post){
151       /* Actions... */
152       if (preg_match('/^acl_edit_.*_x/', $name)){
153         $this->dialogState= 'create';
154         $this->dialog= TRUE;
155         $this->currentIndex= preg_replace('/^acl_edit_([0-9]+).*$/', '\1', $name);
156         $this->loadAclEntry();
157         continue;
158       }
159       if (preg_match('/^acl_del_.*_x/', $name)){
160         unset($this->gosaAclEntry[preg_replace('/^acl_del_([0-9]+).*$/', '\1', $name)]);
161         continue;
162       }
164       if (preg_match('/^cat_edit_.*_x/', $name)){
165         $this->aclObject= preg_replace('/^cat_edit_([^_]+)_.*$/', '\1', $name);
166         $this->dialogState= 'edit';
167         foreach ($this->ocMapping[$this->aclObject] as $oc){
168           if (isset($this->aclContents[$oc])){
169             $this->savedAclContents[$oc]= $this->aclContents[$oc];
170           }
171         }
172         continue;
173       }
174       if (preg_match('/^cat_del_.*_x/', $name)){
175         $idx= preg_replace('/^cat_del_([^_]+)_.*$/', '\1', $name);
176         foreach ($this->ocMapping[$idx] as $key){
177           unset($this->aclContents[$key]);
178         }
179         continue;
180       }
182       /* Sorting... */
183       if (preg_match('/^sortup_.*_x/', $name)){
184         $index= preg_replace('/^sortup_([0-9]+).*$/', '\1', $name);
185         if ($index > 0){
186           $tmp= $this->gosaAclEntry[$index];
187           $this->gosaAclEntry[$index]= $this->gosaAclEntry[$index-1];
188           $this->gosaAclEntry[$index-1]= $tmp;
189         }
190         continue;
191       }
192       if (preg_match('/^sortdown_.*_x/', $name)){
193         $index= preg_replace('/^sortdown_([0-9]+).*$/', '\1', $name);
194         if ($index < count($this->gosaAclEntry)-1){
195           $tmp= $this->gosaAclEntry[$index];
196           $this->gosaAclEntry[$index]= $this->gosaAclEntry[$index+1];
197           $this->gosaAclEntry[$index+1]= $tmp;
198         }
199         continue;
200       }
202       /* ACL saving... */
203       if (preg_match('/^acl_.*_[^xy]$/', $name)){
204         $aclDialog= TRUE;
205         list($dummy, $object, $attribute, $value)= split('_', $name);
207         /* Ordinary ACLs */
208         if (!isset($new_acl[$object])){
209           $new_acl[$object]= array();
210         }
211         if (isset($new_acl[$object][$attribute])){
212           $new_acl[$object][$attribute].= $value;
213         } else {
214           $new_acl[$object][$attribute]= $value;
215         }
216       }
218     }
219     
220     /* Only be interested in new acl's, if we're in the right _POST place */
221     if ($aclDialog && isset($this->ocMapping[$this->aclObject])){
222       foreach ($this->ocMapping[$this->aclObject] as $oc){
223         unset($this->aclContents[$oc]);
224         if (isset($new_acl[$oc])){
225           $this->aclContents[$oc]= $new_acl[$oc];
226         }
227       }
228     }
230     /* Cancel new acl? */
231     if (isset($_POST['cancel_new_acl'])){
232       $this->dialogState= 'head';
233       $this->dialog= FALSE;
234       if ($this->wasNewEntry){
235         unset ($this->gosaAclEntry[$this->currentIndex]);
236       }
237     }
239     /* Store ACL in mail object? */
240     if (isset($_POST['submit_new_acl'])){
241       $this->gosaAclEntry[$this->currentIndex]['type']= $this->aclType;
242       $this->gosaAclEntry[$this->currentIndex]['members']= $this->recipients;
243       $this->gosaAclEntry[$this->currentIndex]['acl']= $this->aclContents;
244       $this->dialogState= 'head';
245       $this->dialog= FALSE;
246     }
248     /* Cancel edit acl? */
249     if (isset($_POST['cancel_edit_acl'])){
250       $this->dialogState= 'create';
251       foreach ($this->ocMapping[$this->aclObject] as $oc){
252         if (isset($this->savedAclContents[$oc])){
253           $this->aclContents[$oc]= $this->savedAclContents[$oc];
254         }
255       }
256     }
258     /* Save edit acl? */
259     if (isset($_POST['submit_edit_acl'])){
260       $this->dialogState= 'create';
261     }
263     /* Add acl? */
264     if (isset($_POST['add_acl']) && $_POST['aclObject'] != ""){
265       $this->dialogState= 'edit';
266       $this->savedAclContents= array();
267       foreach ($this->ocMapping[$this->aclObject] as $oc){
268         if (isset($this->aclContents[$oc])){
269           $this->savedAclContents[$oc]= $this->aclContents[$oc];
270         }
271       }
272     }
274     /* Add to list? */
275     if (isset($_POST['add']) && isset($_POST['source'])){
276       foreach ($_POST['source'] as $key){
277         if ($this->target == 'user'){
278           $this->recipients[$key]= $this->users[$key];
279         }
280         if ($this->target == 'group'){
281           $this->recipients[$key]= $this->groups[$key];
282         }
283       }
284       ksort($this->recipients);
285     }
287     /* Remove from list? */
288     if (isset($_POST['del']) && isset($_POST['recipient'])){
289       foreach ($_POST['recipient'] as $key){
290           unset($this->recipients[$key]);
291       }
292     }
294     /* Save common values */
295     foreach (array("aclType", "aclObject", "target") as $key){
296       if (isset($_POST[$key])){
297         $this->$key= validate($_POST[$key]);
298       }
299     }
301     /* Create templating instance */
302     $smarty= get_smarty();
304     if ($this->dialogState == 'head'){
305       /* Draw list */
306       $aclList= new DivSelectBox("aclList");
307       $aclList->SetHeight(450);
308       
309       /* Fill in entries */
310       foreach ($this->gosaAclEntry as $key => $entry){
311         $field1= array("string" => $this->aclTypes[$entry['type']], "attach" => "style='width:100px'");
312         $field2= array("string" => $this->assembleAclSummary($entry));
313         $action= "<input type='image' name='sortup_$key' alt='up' title='"._("Up")."' src='images/sort_up.png' align='top'>";
314         $action.= "<input type='image' name='sortdown_$key' alt='down' title='"._("Down")."' src='images/sort_down.png'>";
315         $action.= "<input class='center' type='image' src='images/edit.png' alt='"._("edit")."' name='acl_edit_$key' title='"._("Edit ACL")."'>";
316         $action.= "<input class='center' type='image' src='images/edittrash.png' alt='"._("delete")."' name='acl_del_$key' title='"._("Delete ACL")."'>";
318         $field3= array("string" => $action, "attach" => "style='border-right:0px;width:50px';text-align:right");
319         $aclList->AddEntry(array($field1, $field2, $field3));
320       }
322       $smarty->assign("aclList", $aclList->DrawList());
323     }
325     if ($this->dialogState == 'create'){
326       /* Draw list */
327       $aclList= new DivSelectBox("aclList");
328       $aclList->SetHeight(150);
330       /* Add settings for all categories to the (permanent) list */
331       foreach ($this->aclObjects as $oc => $dsc){
332         $summary= "";
333         foreach ($plist as $key => $plugin){
334           if (isset($plugin['plDepends']['objectClass']) && $plugin['plDepends']['objectClass'] == $oc &&
335               isset($this->aclContents[$key])){
336             if (count($this->aclContents[$key]) && isset($this->aclContents[$key][0]) &&
337                 $this->aclContents[$key][0] != ""){
338               $summary.= "$key, ";
339             }
340           }
341         }
343         /* Set summary... */
344         if ($summary == ""){
345           $summary= _("No ACL settings for this category");
346         } else {
347           $summary= sprintf(_("Contains ACLs for these objects: %s"), preg_replace('/, $/', '', $summary));
348         }
350         $field1= array("string" => $dsc, "attach" => "style='width:100px'");
351         $field2= array("string" => $summary);
352         $action= "<input class='center' type='image' src='images/edit.png' alt='"._("edit")."' name='cat_edit_$oc' title='"._("Edit categories ACLs")."'>";
353         $action.= "<input class='center' type='image' src='images/edittrash.png' alt='"._("delete")."' name='cat_del_$oc' title='"._("Clear categories ACLs")."'>";
354         $field3= array("string" => $action, "attach" => "style='border-right:0px;width:50px'");
355         $aclList->AddEntry(array($field1, $field2, $field3));
356       }
358       $smarty->assign("aclList", $aclList->DrawList());
359       $smarty->assign("aclType", $this->aclType);
360       $smarty->assign("aclTypes", $this->aclTypes);
361       $smarty->assign("target", $this->target);
362       $smarty->assign("targets", $this->targets);
364       /* Assign possible target types */
365       $smarty->assign("targets", $this->targets);
366       foreach ($this->attributes as $attr){
367         $smarty->assign($attr, $this->$attr);
368       }
371       /* Generate list */
372       $tmp= array();
373       foreach (array("user" => "users", "group" => "groups") as $field => $arr){
374         if ($this->target == $field){
375           foreach ($this->$arr as $key => $value){
376             if (!isset($this->recipients[$key])){
377               $tmp[$key]= $value;
378             }
379           }
380         }
381       }
382       $smarty->assign('sources', $tmp);
383       $smarty->assign('recipients', $this->recipients);
385       /* Acl selector if scope is base */
386       if ($this->aclType == 'base'){
387         $smarty->assign('aclSelector', $this->buildAclSelector($this->myAclObjects));
388       }
389     }
391     if ($this->dialogState == 'edit'){
392       $smarty->assign('headline', sprintf(_("Edit ACL for '%s', scope is '%s'"), $this->aclObjects[$this->aclObject], $this->aclTypes[$this->aclType]));
394       /* Collect objects for selected category */
395       $aclObjects= array();
396       foreach ($plist as $class => $acls){
397         if (isset($acls['plDepends']['objectClass']) && $acls['plDepends']['objectClass'] == $this->aclObject){
398           $aclObjects[$class]= $acls['plDescription'];
399         }
400       }
402       $smarty->assign('aclSelector', $this->buildAclSelector($aclObjects));
403     }
405     /* Show main page */
406     $smarty->assign("dialogState", $this->dialogState);
407     return ($smarty->fetch (get_template_path('contents.tpl', TRUE, get_base_dir().'/plugins/admin/acl')));
408   }
410   
411   function buildAclSelector($list)
412   {
413     $display= "";
414     $cols= 4;
415     $tmp= get_global('plist');
416     $plist= $tmp->info;
417     asort($plist);
419     foreach ($list as $key => $name){
421       /* Create sub acl if it does not exist */
422       if (!isset($this->aclContents[$key])){
423         $this->aclContents[$key]= array();
424       }
425       if (!isset($this->aclContents[$key][0])){
426         $this->aclContents[$key][0]= '';
427       }
428       $currentAcl= $this->aclContents[$key];
430       /* Object header */
431       $display.= "<table style='width:100%;border:1px solid #A0A0A0' cellspacing=0 cellpadding=2><tr><td style='background-color:#C8C8C8;height:1.8em' colspan=$cols><b>"._("Object").":</b> $name</td></tr>";
433       /* Generate options */
434       $spc= "&nbsp;&nbsp;";
435       if ($this->isContainer && $this->aclType != 'base'){
436         $options= $this->mkchkbx($key."_0_c",  _("Create objects"), preg_match('/c/', $currentAcl[0])).$spc;
437         $options.= $this->mkchkbx($key."_0_m", _("Move objects"), preg_match('/m/', $currentAcl[0])).$spc;
438         $options.= $this->mkchkbx($key."_0_d", _("Remove objects"), preg_match('/d/', $currentAcl[0])).$spc;
439         if ($plist[$key]['plSelfModify']){
440           $options.= $this->mkchkbx($key."_0_s", _("Modifyable by owner"), preg_match('/s/', $currentAcl[0])).$spc;
441         }
442       } else {
443         $options= $this->mkchkbx($key."_0_m", _("Move object"), preg_match('/m/', $currentAcl[0])).$spc;
444         $options.= $this->mkchkbx($key."_0_d", _("Remove object"), preg_match('/d/', $currentAcl[0])).$spc;
445         if ($plist[$key]['plSelfModify']){
446           $options.= $this->mkchkbx($key."_0_s", _("Modifyable by owner"), preg_match('/s/', $currentAcl[0])).$spc;
447         }
448       }
450       $display.= "<tr><td style='background-color:#E0E0E0' colspan=$cols>$options</td></tr>";
452       /* Walk through the list of attributes */
453       $cnt= 1;
454       $splist= $plist[$key];
455       asort($splist);
456       foreach($splist as $attr => $dsc){
458         /* Skip pl* attributes, they are internal... */
459         if (preg_match('/^pl[A-Z]+.*$/', $attr)){
460           continue;
461         }
463         /* Open table row */
464         if ($cnt == 1){
465           $display.= "<tr>";
466         }
468         /* Close table row */
469         if ($cnt == $cols){
470           $cnt= 1;
471           $rb= "";
472           $end= "</tr>";
473         } else {
474           $cnt++;
475           $rb= "border-right:1px solid #A0A0A0;";
476           $end= "";
477         }
479         /* Collect list of attributes */
480         $state= "";
481         if (isset($currentAcl[$attr])){
482           $state= $currentAcl[$attr];
483         }
484         $display.= "<td style='border-top:1px solid #A0A0A0;${rb}width:".(int)(100/$cols)."%'><b>$dsc</b> ($attr)<br>".$this->mkrwbx($key."_".$attr, $state)."</td>$end";
485       }
486       
487       /* Fill missing td's if needed */
488       if (--$cnt != $cols){
489        $display.= str_repeat("<td style='border-top:1px solid #A0A0A0'>&nbsp;</td>", $cols-$cnt); 
490       }
492       $display.= "</table><br>";
493     }
495     return ($display);
496   }
499   function mkchkbx($name, $text, $state= FALSE)
500   {
501     $state= $state?"checked":"";
502     return "<input id='acl_$name' type=checkbox name='acl_$name' $state><label for='acl_$name'>$text</label>";
503   }
506   function mkrwbx($name, $state= "")
507   {
508     $rstate= preg_match('/r/', $state)?'checked':'';
509     $wstate= preg_match('/w/', $state)?'checked':'';
510     return ("<input id='acl_${name}_r' type=checkbox name='acl_${name}_r' $rstate><label for='acl_${name}_r'>"._("read")."</label>".
511             "<input id='acl_${name}_w' type=checkbox name='acl_${name}_w' $wstate><label for='acl_${name}_w'>"._("write")."</label>");
512   }
515   function explodeACL($acl)
516   {
517     list($index, $type)= split(':', $acl);
518     $a= array( $index => array("type" => $type,
519                                "members" => $this->extractMembers($acl)));
520     
521     /* Handle different types */
522     switch ($type){
524       case 'psub':
525       case 'sub':
526       case 'one':
527       case 'base':
528         $a[$index]['acl']= $this->extractACL($acl);
529         break;
530       
531       case 'role':
532         echo "Role";
533         break;
535       case 'reset':
536         break;
537       
538       default:
539         print_red(sprintf(_("Unkown ACL type '%s'. Don't know how to handle it."), $type));
540         $a= array();
541     }
542     
543     return ($a);
544   }
547   function extractMembers($acl)
548   {
549     $a= array();
551     /* Rip acl off the string, seperate by ',' and place it in an array */
552     $ms= preg_replace('/^[^:]+:[^:]+:([^:]+).*$/', '\1', $acl);
553     if ($ms == $acl){
554       return $a;
555     }
556     $ma= split(',', $ms);
558     /* Decode dn's, fill with informations from LDAP */
559     $ldap= $this->config->get_ldap_link();
560     foreach ($ma as $memberdn){
561       $dn= base64_decode($memberdn);
562       $ldap->cat($dn, array('cn', 'objectClass', 'description', 'uid'));
564       /* Found entry... */
565       if ($ldap->count()){
566         $attrs= $ldap->fetch();
567         if (in_array_ics('gosaAccount', $attrs['objectClass'])){
568           $a['U:'.$dn]= $attrs['cn'][0]." [".$attrs['uid'][0]."]";
569         } else {
570           $a['G:'.$dn]= $attrs['cn'][0];
571           if (isset($attrs['description'][0])){
572             $a['G:'.$dn].= " [".$attrs['description'][0]."]";
573           }
574         }
576       /* ... or not */
577       } else {
578         $a['U:'.$dn]= sprintf(_("Unknown entry '%s'!"), $dn);
579       }
580     }
582     return ($a);
583   }
586   function extractACL($acl)
587   {
588     /* Rip acl off the string, seperate by ',' and place it in an array */
589     $as= preg_replace('/^[^:]+:[^:]+:[^:]+:(.*)$/', '\1', $acl);
590     $aa= split(',', $as);
591     $a= array();
593     /* Dis-assemble single ACLs */
594     foreach($aa as $sacl){
595       
596       /* Dis-assemble field ACLs */
597       $ao= split('#', $sacl);
598       $gobject= "";
599       foreach($ao as $idx => $ssacl){
601         /* First is department with global acl */
602         $object= preg_replace('/^([^;]+);.*$/', '\1', $ssacl);
603         $gacl=   preg_replace('/^[^;]+;(.*)$/', '\1', $ssacl);
604         if ($idx == 0){
605           /* Create hash for this object */
606           $gobject= $object;
607           $a[$gobject]= array();
609           /* Append ACL if set */
610           if ($gacl != ""){
611             $a[$gobject]= array($gacl);
612           }
613         } else {
615           /* All other entries get appended... */
616           list($field, $facl)= split(';', $ssacl);
617           $a[$gobject][$field]= $facl;
618         }
620       }
621     }
623     return ($a);
624   }
626   
627   function assembleAclSummary($entry)
628   {
629     $summary= "";
631     /* Summarize ACL */
632     if (isset($entry['acl'])){
633       $acl= "";
634       foreach ($entry['acl'] as $name => $object){
635         $acl.= "$name, ";
636       }
637       $summary.= sprintf(_("Contains settings for these objects: %s"), preg_replace('/, $/', '', $acl));
638     }
640     /* Summarize members */
641     if ($summary != ""){
642       $summary.= ", ";
643     }
644     if (count($entry['members'])){
645       $summary.= _("Members:")." ";
646       foreach ($entry['members'] as $cn){
647         $cn= preg_replace('/ \[.*$/', '', $cn);
648         $summary.= $cn.", ";
649       }
650     } else {
651       $summary.= _("ACLs is valid for all users");
652     }
654     return (preg_replace('/, $/', '', $summary));
655   }
658   function loadAclEntry($new= FALSE)
659   {
660     /* New entry gets presets... */
661     if ($new){
662       $this->aclType= 'base';
663       $this->recipients= array();
664       $this->aclContents= array();
665     } else {
666       $acl= $this->gosaAclEntry[$this->currentIndex];
667       $this->aclType= $acl['type'];
668       $this->recipients= $acl['members'];
669       $this->aclContents= $acl['acl'];
670     }
672     $this->wasNewEntry= $new;
673   }
676   function aclPostHandler()
677   {
678     if (isset($_POST['save_acl'])){
679       $this->save();
680       return TRUE;
681     }
683     return FALSE;
684   }
687   function save()
688   {
689     /* Assemble ACL's */
690     $tmp_acl= array();
691     foreach ($this->gosaAclEntry as $prio => $entry){
692       $final= "";
693       $members= "";
694       foreach ($entry['members'] as $key => $dummy){
695         $members.= base64_encode(preg_replace('/^.:/', '', $key)).',';
696       }
697       $final= $prio.":".$entry['type'].":".preg_replace('/,$/', '', $members);
699       /* ACL's if needed */
700       if ($entry['type'] != "reset" && $entry['type'] != "role"){
701         $acl= ":";
702         foreach ($entry['acl'] as $object => $contents){
703           $acl.= $object.";";
704           
705           foreach($contents as $attr => $permission){
707             /* First entry? Its the one for global settings... */
708             if ($attr == '0'){
709               $acl.= $permission;
710             } else {
711               $acl.= '#'.$attr.';'.$permission;
712             }
714           }
715           $acl.= ',';
717         }
718         $final.= preg_replace('/,$/', '', $acl);
719       }
721       $tmp_acl[]= $final;
722     } 
724     /* Finally (re-)assign it... */
725     $this->gosaAclEntry= $tmp_acl;
727     /* Call main method */
728     plugin::save();
730     /* Remove acl from this entry if it is empty... */
731     if (!count($this->gosaAclEntry)){
732       /* Remove attribute */
733       if ($this->initially_was_account){
734         $attrs['gosaAclEntry']= array();
735       } else {
736         unset($attrs['gosaAclEntry']);
737       }
739       /* Remove object class */
740       $this->attrs['objectClass']= array_remove_entries(array('gosaAcl'), $this->attrs['objectClass']);
741     }    
743     /* Do LDAP modifications */
744     $ldap= $this->config->get_ldap_link();
745     $ldap->cd($this->dn);
746     $this->cleanup();
747     $ldap->modify ($this->attrs);
749     show_ldap_error($ldap->get_error(), sprintf(_("Saving ACLs with dn '%s' failed."),$this->dn));
750   }
753   function remove_from_parent()
754   {
755     echo "remove_from_parent() called";
756   }
760 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
761 ?>