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 acl extends plugin
24 {
25 /* Definitions */
26 var $plHeadline= "Access control";
27 var $plDescription= "Manage access control lists";
29 /* attribute list for save action */
30 var $attributes= array('gosaAclEntry');
31 var $objectclasses= array('gosaAcl');
33 /* Helpers */
34 var $dialogState= "head";
35 var $gosaAclEntry= array();
36 var $aclType= "";
37 var $aclObject= "";
38 var $aclContents= array();
39 var $target= "group";
40 var $aclTypes= array();
41 var $aclObjects= array();
42 var $aclFilter= "";
43 var $aclMyObjects= array();
44 var $users= array();
45 var $roles= array();
46 var $groups= array();
47 var $recipients= array();
48 var $isContainer= FALSE;
49 var $currentIndex= 0;
50 var $wasNewEntry= FALSE;
51 var $ocMapping= array();
52 var $savedAclContents= array();
53 var $myAclObjects = array();
54 var $acl_category = "acl/";
56 function acl (&$config, $parent, $dn= NULL)
57 {
58 /* Include config object */
59 plugin::plugin($config, $dn);
61 /* Load ACL's */
62 $this->gosaAclEntry= array();
63 if (isset($this->attrs['gosaAclEntry'])){
64 for ($i= 0; $i<$this->attrs['gosaAclEntry']['count']; $i++){
65 $acl= $this->attrs['gosaAclEntry'][$i];
66 $this->gosaAclEntry= array_merge($this->gosaAclEntry, acl::explodeACL($acl));
67 }
68 }
69 ksort($this->gosaAclEntry);
71 /* Save parent - we've to know more about it than other plugins... */
72 $this->parent= &$parent;
74 /* Container? */
75 if (preg_match('/^(o|ou|c|l|dc)=/i', $dn)){
76 $this->isContainer= TRUE;
77 }
79 /* Users */
80 $ui= get_userinfo();
81 $tag= $ui->gosaUnitTag;
82 $ldap= $config->get_ldap_link();
83 $ldap->cd($config->current['BASE']);
84 if ($tag == ""){
85 $ldap->search('(objectClass=gosaAccount)', array('uid', 'cn'));
86 } else {
87 $ldap->search('(&(objectClass=gosaAccount)(gosaUnitTag='.$tag.'))', array('uid', 'cn'));
88 }
89 while ($attrs= $ldap->fetch()){
91 // Allow objects without cn to be listed without causing an error.
92 if(!isset($attrs['cn'][0]) && isset($attrs['uid'][0])){
93 $this->users['U:'.$attrs['dn']]= $attrs['uid'][0];
94 }elseif(!isset($attrs['uid'][0]) && isset($attrs['cn'][0])){
95 $this->users['U:'.$attrs['dn']]= $attrs['cn'][0];
96 }elseif(!isset($attrs['uid'][0]) && !isset($attrs['cn'][0])){
97 $this->users['U:'.$attrs['dn']]= $attrs['dn'];
98 }else{
99 $this->users['U:'.$attrs['dn']]= $attrs['cn'][0].' ['.$attrs['uid'][0].']';
100 }
102 }
103 ksort($this->users);
105 /* Groups */
106 $ldap->cd($config->current['BASE']);
107 # if ($tag == ""){
108 $ldap->search('(objectClass=posixGroup)', array('cn', 'description'));
109 # } else {
110 # $ldap->search('(&(objectClass=posixGroup)(gosaUnitTag='.$tag.'))', array('cn', 'description'));
111 # }
112 while ($attrs= $ldap->fetch()){
113 $dsc= "";
114 if (isset($attrs['description'][0])){
115 $dsc= $attrs['description'][0];
116 }
117 $this->groups['G:'.$attrs['dn']]= $attrs['cn'][0].' ['.$dsc.']';
118 }
119 ksort($this->groups);
121 /* Roles */
122 $ldap->cd($config->current['BASE']);
123 # if ($tag == ""){
124 $ldap->search('(objectClass=gosaRole)', array('cn', 'description','gosaAclTemplate','dn'));
125 # } else {
126 # $ldap->search('(&(objectClass=gosaRole)(gosaUnitTag='.$tag.'))', array('cn', 'description','gosaAclTemplate','dn'));
127 # }
128 while ($attrs= $ldap->fetch()){
129 $dsc= "";
130 if (isset($attrs['description'][0])){
131 $dsc= $attrs['description'][0];
132 }
134 $role_id = $attrs['dn'];
136 $this->roles[$role_id]['acls'] =array();
137 for ($i= 0; $i < $attrs['gosaAclTemplate']['count']; $i++){
138 $acl= $attrs['gosaAclTemplate'][$i];
139 $this->roles[$role_id]['acls'] = array_merge($this->roles[$role_id]['acls'],acl::explodeACL($acl));
140 }
141 $this->roles[$role_id]['description'] = $dsc;
142 $this->roles[$role_id]['cn'] = $attrs['cn'][0];
143 }
145 /* Objects */
146 $tmp= session::global_get('plist');
147 $plist= $tmp->info;
148 $cats = array();
149 if (isset($this->parent) && $this->parent !== NULL){
150 $oc= array();
151 foreach ($this->parent->by_object as $key => $obj){
152 $oc= array_merge($oc, $obj->objectclasses);
153 if(isset($obj->acl_category)){
154 $tmp= str_replace("/","",$obj->acl_category);
155 $cats[$tmp] = $tmp;
156 }
157 }
158 if (in_array_ics('organizationalUnit', $oc)){
159 $this->isContainer= TRUE;
160 }
161 } else {
162 $oc= $this->attrs['objectClass'];
163 }
165 /* Extract available categories from plugin info list */
166 foreach ($plist as $class => $acls){
168 /* Only feed categories */
169 if (isset($acls['plCategory'])){
171 /* Walk through supplied list and feed only translated categories */
172 foreach($acls['plCategory'] as $idx => $data){
174 /* Non numeric index means -> base object containing more informations */
175 if (preg_match('/^[0-9]+$/', $idx)){
177 if (!isset($this->ocMapping[$data])){
178 $this->ocMapping[$data]= array();
179 $this->ocMapping[$data][]= '0';
180 }
182 if(isset($cats[$data])){
183 $this->myAclObjects[$data.'/'.$class]= $acls['plDescription'];
184 }
185 $this->ocMapping[$data][]= $class;
186 } else {
187 if (!isset($this->ocMapping[$idx])){
188 $this->ocMapping[$idx]= array();
189 $this->ocMapping[$idx][]= '0';
190 }
191 $this->ocMapping[$idx][]= $class;
192 $this->aclObjects[$idx]= $data['description'];
194 /* Additionally filter the classes we're interested in in "self edit" mode */
195 if (is_array($data['objectClass'])){
196 foreach($data['objectClass'] as $objectClass){
197 if (in_array_ics($objectClass, $oc)){
198 $this->myAclObjects[$idx.'/'.$class]= $acls['plDescription'];
199 break;
200 }
201 }
202 } else {
203 if (in_array_ics($data['objectClass'], $oc)){
204 $this->myAclObjects[$idx.'/'.$class]= $acls['plDescription'];
205 }
206 }
207 }
209 }
210 }
211 }
212 $this->aclObjects['all']= '* '._("All categories");
213 $this->ocMapping['all']= array('0' => 'all');
215 /* Sort categories */
216 asort($this->aclObjects);
218 /* Fill acl types */
219 if ($this->isContainer){
220 $this->aclTypes= array("reset" => _("Reset ACLs"),
221 "one" => _("One level"),
222 "base" => _("Current object"),
223 "sub" => _("Complete subtree"),
224 "psub" => _("Complete subtree (permanent)"),
225 "role" => _("Use ACL defined in role"));
226 } else {
227 $this->aclTypes= array("base" => _("Current object"),
228 "role" => _("Use ACL defined in role"));
229 }
230 asort($this->aclTypes);
231 $this->targets= array("user" => _("Users"), "group" => _("Groups"));
232 asort($this->targets);
234 /* Finally - we want to get saved... */
235 $this->is_account= TRUE;
236 }
239 function execute()
240 {
241 /* Call parent execute */
242 plugin::execute();
244 $tmp= session::global_get('plist');
245 $plist= $tmp->info;
247 /* Handle posts */
248 if (isset($_POST['new_acl'])){
249 $this->dialogState= 'create';
250 $this->dialog= TRUE;
251 $this->currentIndex= count($this->gosaAclEntry);
252 $this->loadAclEntry(TRUE);
253 }
255 $new_acl= array();
256 $aclDialog= FALSE;
257 $firstedit= FALSE;
259 /* Act on HTML post and gets here.
260 */
261 if(isset($_GET['id']) && isset($_GET['act']) && $_GET['act'] == "edit"){
262 $id = trim($_GET['id']);
263 $this->dialogState= 'create';
264 $firstedit= TRUE;
265 $this->dialog= TRUE;
266 $this->currentIndex= $id;
267 $this->loadAclEntry();
268 }
270 foreach($_POST as $name => $post){
272 /* Actions... */
273 if (preg_match('/^acl_edit_.*_x/', $name)){
274 $this->dialogState= 'create';
275 $firstedit= TRUE;
276 $this->dialog= TRUE;
277 $this->currentIndex= preg_replace('/^acl_edit_([0-9]+).*$/', '\1', $name);
278 $this->loadAclEntry();
279 continue;
280 }
282 if (preg_match('/^cat_edit_.*_x/', $name)){
283 $this->aclObject= preg_replace('/^cat_edit_([^_]+)_.*$/', '\1', $name);
284 $this->dialogState= 'edit';
285 foreach ($this->ocMapping[$this->aclObject] as $oc){
286 if (isset($this->aclContents[$oc])){
287 $this->savedAclContents[$oc]= $this->aclContents[$oc];
288 }
289 }
290 continue;
291 }
293 /* Only handle posts, if we allowed to modify ACLs */
294 if(!$this->acl_is_writeable("")){
295 continue;
296 }
298 if (preg_match('/^acl_del_.*_x/', $name)){
299 unset($this->gosaAclEntry[preg_replace('/^acl_del_([0-9]+).*$/', '\1', $name)]);
300 continue;
301 }
303 if (preg_match('/^cat_del_.*_x/', $name)){
304 $idx= preg_replace('/^cat_del_([^_]+)_.*$/', '\1', $name);
305 foreach ($this->ocMapping[$idx] as $key){
306 unset($this->aclContents["$idx/$key"]);
307 }
308 continue;
309 }
311 /* Sorting... */
312 if (preg_match('/^sortup_.*_x/', $name)){
313 $index= preg_replace('/^sortup_([0-9]+).*$/', '\1', $name);
314 if ($index > 0){
315 $tmp= $this->gosaAclEntry[$index];
316 $this->gosaAclEntry[$index]= $this->gosaAclEntry[$index-1];
317 $this->gosaAclEntry[$index-1]= $tmp;
318 }
319 continue;
320 }
321 if (preg_match('/^sortdown_.*_x/', $name)){
322 $index= preg_replace('/^sortdown_([0-9]+).*$/', '\1', $name);
323 if ($index < count($this->gosaAclEntry)-1){
324 $tmp= $this->gosaAclEntry[$index];
325 $this->gosaAclEntry[$index]= $this->gosaAclEntry[$index+1];
326 $this->gosaAclEntry[$index+1]= $tmp;
327 }
328 continue;
329 }
331 /* ACL saving... */
332 if (preg_match('/^acl_.*_[^xy]$/', $name)){
333 list($dummy, $object, $attribute, $value)= split('_', $name);
335 /* Skip for detection entry */
336 if ($object == 'dummy') {
337 continue;
338 }
340 /* Ordinary ACLs */
341 if (!isset($new_acl[$object])){
342 $new_acl[$object]= array();
343 }
344 if (isset($new_acl[$object][$attribute])){
345 $new_acl[$object][$attribute].= $value;
346 } else {
347 $new_acl[$object][$attribute]= $value;
348 }
349 }
351 if(isset($_POST['selected_role'])){
352 $this->aclContents = "";
353 $this->aclContents = base64_decode($_POST['selected_role']);
354 }
355 }
357 if(isset($_POST['acl_dummy_0_0_0'])){
358 $aclDialog= TRUE;
359 }
361 if($this->acl_is_writeable("")){
363 /* Only be interested in new acl's, if we're in the right _POST place */
364 if ($aclDialog && $this->aclObject != "" && is_array($this->ocMapping[$this->aclObject])){
366 foreach ($this->ocMapping[$this->aclObject] as $oc){
368 if(isset($this->aclContents[$oc]) && is_array($this->aclContents)){
369 unset($this->aclContents[$oc]);
370 }elseif(isset($this->aclContents[$this->aclObject.'/'.$oc]) && is_array($this->aclContents)){
371 unset($this->aclContents[$this->aclObject.'/'.$oc]);
372 }else{
373 # trigger_error("Huhm?");
374 }
375 if (isset($new_acl[$oc]) && is_array($new_acl)){
376 $this->aclContents[$oc]= $new_acl[$oc];
377 }
378 if (isset($new_acl[$this->aclObject.'/'.$oc]) && is_array($new_acl)){
379 $this->aclContents[$this->aclObject.'/'.$oc]= $new_acl[$this->aclObject.'/'.$oc];
380 }
381 }
382 }
384 /* Save new acl in case of base edit mode */
385 if ($this->aclType == 'base' && !$firstedit){
386 $this->aclContents= $new_acl;
387 }
388 }
390 /* Cancel new acl? */
391 if (isset($_POST['cancel_new_acl'])){
392 $this->dialogState= 'head';
393 $this->dialog= FALSE;
394 if ($this->wasNewEntry){
395 unset ($this->gosaAclEntry[$this->currentIndex]);
396 }
397 }
399 /* Save common values */
400 if($this->acl_is_writeable("")){
401 foreach (array("aclType","aclFilter", "aclObject", "target") as $key){
402 if (isset($_POST[$key])){
403 $this->$key= validate($_POST[$key]);
404 }
405 }
406 }
408 /* Store ACL in main object? */
409 if (isset($_POST['submit_new_acl'])){
410 $this->gosaAclEntry[$this->currentIndex]['type']= $this->aclType;
411 $this->gosaAclEntry[$this->currentIndex]['members']= $this->recipients;
412 $this->gosaAclEntry[$this->currentIndex]['acl']= $this->aclContents;
413 $this->gosaAclEntry[$this->currentIndex]['filter']= $this->aclFilter;
414 $this->dialogState= 'head';
415 $this->dialog= FALSE;
416 }
418 /* Cancel edit acl? */
419 if (isset($_POST['cancel_edit_acl'])){
420 $this->dialogState= 'create';
421 foreach ($this->ocMapping[$this->aclObject] as $oc){
422 if (isset($this->savedAclContents[$oc])){
423 $this->aclContents[$oc]= $this->savedAclContents[$oc];
424 }
425 }
426 }
428 /* Save edit acl? */
429 if (isset($_POST['submit_edit_acl'])){
430 $this->dialogState= 'create';
431 }
433 /* Add acl? */
434 if (isset($_POST['add_acl']) && $_POST['aclObject'] != ""){
435 $this->dialogState= 'edit';
436 $this->savedAclContents= array();
437 foreach ($this->ocMapping[$this->aclObject] as $oc){
438 if (isset($this->aclContents[$oc])){
439 $this->savedAclContents[$oc]= $this->aclContents[$oc];
440 }
441 }
442 }
444 /* Add to list? */
445 if (isset($_POST['add']) && isset($_POST['source'])){
446 foreach ($_POST['source'] as $key){
447 if ($this->target == 'user'){
448 $this->recipients[$key]= $this->users[$key];
449 }
450 if ($this->target == 'group'){
451 $this->recipients[$key]= $this->groups[$key];
452 }
453 }
454 ksort($this->recipients);
455 }
457 /* Remove from list? */
458 if (isset($_POST['del']) && isset($_POST['recipient'])){
459 foreach ($_POST['recipient'] as $key){
460 unset($this->recipients[$key]);
461 }
462 }
464 /* Create templating instance */
465 $smarty= get_smarty();
466 $smarty->assign("acl_readable",$this->acl_is_readable(""));
467 if(!$this->acl_is_readable("")){
468 return ($smarty->fetch (get_template_path('acl.tpl')));
469 }
471 if ($this->dialogState == 'head'){
472 /* Draw list */
473 $aclList= new divSelectBox("aclList");
474 $aclList->SetHeight(450);
476 /* Fill in entries */
477 foreach ($this->gosaAclEntry as $key => $entry){
478 if(!$this->acl_is_readable("")) continue;
480 $action ="";
482 if($this->acl_is_readable("")){
483 $link = "<a href=?plug=".$_GET['plug']."&id=".$key."&act=edit>".$this->assembleAclSummary($entry)."</a>";
484 }else{
485 $link = $this->assembleAclSummary($entry);
486 }
488 $field1= array("string" => $this->aclTypes[$entry['type']], "attach" => "style='width:150px'");
489 $field2= array("string" => $link);
491 if($this->acl_is_writeable("")){
492 $action.= "<input type='image' name='sortup_$key' alt='up'
493 title='"._("Up")."' src='images/lists/sort-up.png' align='top'>";
494 $action.= "<input type='image' name='sortdown_$key' alt='down'
495 title='"._("Down")."' src='images/lists/sort-down.png'>";
496 }
498 if($this->acl_is_readable("")){
499 $action.= "<input class='center' type='image' src='images/lists/edit.png'
500 alt='"._("Edit")."' name='acl_edit_$key' title='".msgPool::editButton(_("ACL"))."'>";
501 }
502 if($this->acl_is_removeable("")){
503 $action.= "<input class='center' type='image' src='images/lists/trash.png'
504 alt='"._("Delete")."' name='acl_del_$key' title='".msgPool::delButton(_("ACL"))."'>";
505 }
507 $field3= array("string" => $action, "attach" => "style='border-right:0px;width:50px;text-align:right;'");
508 $aclList->AddEntry(array($field1, $field2, $field3));
509 }
511 $smarty->assign("aclList", $aclList->DrawList());
512 }
514 if ($this->dialogState == 'create'){
515 /* Draw list */
516 $aclList= new divSelectBox("aclList");
517 $aclList->SetHeight(150);
519 /* Add settings for all categories to the (permanent) list */
520 foreach ($this->aclObjects as $section => $dsc){
521 $summary= "";
522 foreach($this->ocMapping[$section] as $oc){
523 if (isset($this->aclContents[$oc]) && count($this->aclContents[$oc]) && isset($this->aclContents[$oc][0]) &&
524 $this->aclContents[$oc][0] != ""){
526 $summary.= "$oc, ";
527 continue;
528 }
529 if (isset($this->aclContents["$section/$oc"]) && count($this->aclContents["$section/$oc"])){
530 $summary.= "$oc, ";
531 continue;
532 }
533 if (isset($this->aclContents[$oc]) && !isset($this->aclContents[$oc][0]) && count($this->aclContents[$oc])){
534 $summary.= "$oc, ";
535 }
536 }
538 /* Set summary... */
539 if ($summary == ""){
540 $summary= '<i>'._("No ACL settings for this category!").'</i>';
541 } else {
542 $summary= sprintf(_("Contains ACLs for these objects: %s"), preg_replace('/, $/', '', $summary));
543 }
545 $actions ="";
546 if($this->acl_is_readable("")){
547 $actions= "<input class='center' type='image' src='images/lists/edit.png'
548 alt='"._("Edit")."' name='cat_edit_$section' title='".msgPool::editButton(_("category ACL"))."'>";
549 }
550 if($this->acl_is_removeable()){
551 $actions.= "<input class='center' type='image' src='images/lists/trash.png'
552 alt='"._("Delete")."' name='cat_del_$section' title='".msgPool::delButton(_("category ACL"))."'>";
553 }
555 $field1= array("string" => $dsc, "attach" => "style='width:100px'");
556 $field2= array("string" => $summary);
557 $field3= array("string" => $actions, "attach" => "style='border-right:0px;width:50px'");
558 $aclList->AddEntry(array($field1, $field2, $field3));
559 }
561 $smarty->assign("aclList", $aclList->DrawList());
562 $smarty->assign("aclType", $this->aclType);
563 $smarty->assign("aclFilter", $this->aclFilter);
564 $smarty->assign("aclTypes", $this->aclTypes);
565 $smarty->assign("target", $this->target);
566 $smarty->assign("targets", $this->targets);
568 /* Assign possible target types */
569 $smarty->assign("targets", $this->targets);
570 foreach ($this->attributes as $attr){
571 $smarty->assign($attr, $this->$attr);
572 }
575 /* Generate list */
576 $tmp= array();
577 foreach (array("user" => "users", "group" => "groups") as $field => $arr){
578 if ($this->target == $field){
579 foreach ($this->$arr as $key => $value){
580 if (!isset($this->recipients[$key])){
581 $tmp[$key]= $value;
582 }
583 }
584 }
585 }
586 $smarty->assign('sources', $tmp);
587 $smarty->assign('recipients', $this->recipients);
589 /* Acl selector if scope is base */
590 if ($this->aclType == 'base'){
591 $smarty->assign('aclSelector', $this->buildAclSelector($this->myAclObjects));
592 }
594 /* Role selector if scope is base */
595 if ($this->aclType == 'role'){
596 $smarty->assign('roleSelector', "Role selector");#, $this->buildRoleSelector($this->myAclObjects));
597 $smarty->assign('roleSelector', $this->buildRoleSelector($this->roles));
598 }
599 }
601 if ($this->dialogState == 'edit'){
602 $smarty->assign('headline', sprintf(_("Edit ACL for '%s' - scope is '%s'"), $this->aclObjects[$this->aclObject], $this->aclTypes[$this->aclType]));
604 /* Collect objects for selected category */
605 foreach ($this->ocMapping[$this->aclObject] as $idx => $class){
606 if ($idx == 0){
607 continue;
608 }
609 $aclObjects[$this->aclObject.'/'.$class]= $plist[$class]['plDescription'];
610 }
611 if ($this->aclObject == 'all'){
612 $aclObjects['all']= _("All objects in current subtree");
613 }
615 /* Role selector if scope is base */
616 if ($this->aclType == 'role'){
617 $smarty->assign('roleSelector', $this->buildRoleSelector($this->roles));
618 } else {
619 $smarty->assign('aclSelector', $this->buildAclSelector($aclObjects));
620 }
621 }
623 /* Show main page */
624 $smarty->assign("dialogState", $this->dialogState);
626 /* Assign acls */
627 $smarty->assign("acl_createable",$this->acl_is_createable());
628 $smarty->assign("acl_writeable" ,$this->acl_is_writeable(""));
629 $smarty->assign("acl_readable" ,$this->acl_is_readable(""));
630 $smarty->assign("acl_removeable",$this->acl_is_removeable());
632 return ($smarty->fetch (get_template_path('acl.tpl')));
633 }
636 function sort_by_priority($list)
637 {
638 $tmp= session::global_get('plist');
639 $plist= $tmp->info;
640 asort($plist);
641 $newSort = array();
643 foreach($list as $name => $translation){
644 $na = preg_replace("/^.*\//","",$name);
645 $prio = 0;
646 if(isset($plist[$na]['plPriority'])){
647 $prio= $plist[$na]['plPriority'] ;
648 }
650 $newSort[$name] = $prio;
651 }
653 asort($newSort);
655 $ret = array();
656 foreach($newSort as $name => $prio){
657 $ret[$name] = $list[$name];
658 }
659 return($ret);
660 }
663 function buildRoleSelector($list)
664 {
665 $D_List =new divSelectBox("Acl_Roles");
667 $selected = $this->aclContents;
668 if(!is_string($this->aclContents) || !isset($list[$this->aclContents])){
669 $selected = key($list);
670 }
672 $str ="";
673 foreach($list as $dn => $values){
675 if($dn == $selected){
676 $option = "<input type='radio' name='selected_role' value='".base64_encode($dn)."' checked>";
677 }else{
678 $option = "<input type='radio' name='selected_role' value='".base64_encode($dn)."'>";
679 }
681 $field1 = array("string" => $option) ;
682 $field2 = array("string" => $values['cn'], "attach" => "style='width:200px;'") ;
683 $field3 = array("string" => $values['description'],"attach" => "style='border-right:0px;'") ;
685 $D_List->AddEntry(array($field1,$field2,$field3));
686 }
687 return($D_List->DrawList());
688 }
691 function buildAclSelector($list)
692 {
693 $display= "<input type='hidden' name='acl_dummy_0_0_0' value='1'>";
694 $cols= 3;
695 $tmp= session::global_get('plist');
696 $plist= $tmp->info;
697 asort($plist);
699 /* Add select all/none buttons */
700 $style = "style='width:100px;'";
702 if($this->acl_is_writeable("")){
703 $display .= "<input ".$style." type='button' name='toggle_all_create' onClick=\"acl_toggle_all('_0_c$');\" value='Toggle C'>";
704 $display .= "<input ".$style." type='button' name='toggle_all_move' onClick=\"acl_toggle_all('_0_m$');\" value='Toggle M'>";
705 $display .= "<input ".$style." type='button' name='toggle_all_remove' onClick=\"acl_toggle_all('_0_d$');\" value='Toggle D'> - ";
706 $display .= "<input ".$style." type='button' name='toggle_all_read' onClick=\"acl_toggle_all('_0_r$');\" value='Toggle R'>";
707 $display .= "<input ".$style." type='button' name='toggle_all_write' onClick=\"acl_toggle_all('_0_w$');\" value='Toggle W'> - ";
709 $display .= "<input ".$style." type='button' name='toggle_all_sub_read' onClick=\"acl_toggle_all('[^0]_r$');\" value='R+'>";
710 $display .= "<input ".$style." type='button' name='toggle_all_sub_write' onClick=\"acl_toggle_all('[^0]_w$');\" value='W+'>";
712 $display .= "<br>";
714 $style = "style='width:50px;'";
715 $display .= "<input ".$style." type='button' name='set_true_all_create' onClick=\"acl_set_all('_0_c$',true);\" value='C+'>";
716 $display .= "<input ".$style." type='button' name='set_false_all_create' onClick=\"acl_set_all('_0_c$',false);\" value='C-'>";
717 $display .= "<input ".$style." type='button' name='set_true_all_move' onClick=\"acl_set_all('_0_m$',true);\" value='M+'>";
718 $display .= "<input ".$style." type='button' name='set_false_all_move' onClick=\"acl_set_all('_0_m$',false);\" value='M-'>";
719 $display .= "<input ".$style." type='button' name='set_true_all_remove' onClick=\"acl_set_all('_0_d$',true);\" value='D+'>";
720 $display .= "<input ".$style." type='button' name='set_false_all_remove' onClick=\"acl_set_all('_0_d$',false);\" value='D-'> - ";
721 $display .= "<input ".$style." type='button' name='set_true_all_read' onClick=\"acl_set_all('_0_r$',true);\" value='R+'>";
722 $display .= "<input ".$style." type='button' name='set_false_all_read' onClick=\"acl_set_all('_0_r$',false);\" value='R-'>";
723 $display .= "<input ".$style." type='button' name='set_true_all_write' onClick=\"acl_set_all('_0_w$',true);\" value='W+'>";
724 $display .= "<input ".$style." type='button' name='set_false_all_write' onClick=\"acl_set_all('_0_w$',false);\" value='W-'> - ";
726 $display .= "<input ".$style." type='button' name='set_true_all_read' onClick=\"acl_set_all('[^0]_r$',true);\" value='R+'>";
727 $display .= "<input ".$style." type='button' name='set_false_all_read' onClick=\"acl_set_all('[^0]_r$',false);\" value='R-'>";
728 $display .= "<input ".$style." type='button' name='set_true_all_write' onClick=\"acl_set_all('[^0]_w$',true);\" value='W+'>";
729 $display .= "<input ".$style." type='button' name='set_false_all_write' onClick=\"acl_set_all('[^0]_w$',false);\" value='W-'>";
730 }
732 /* Build general objects */
733 $list =$this->sort_by_priority($list);
734 foreach ($list as $key => $name){
736 /* Create sub acl if it does not exist */
737 if (!isset($this->aclContents[$key])){
738 $this->aclContents[$key]= array();
739 }
740 if(!isset($this->aclContents[$key][0])){
741 $this->aclContents[$key][0]= '';
742 }
744 $currentAcl= $this->aclContents[$key];
746 /* Get the overall plugin acls
747 */
748 $overall_acl ="";
749 if(isset($currentAcl[0])){
750 $overall_acl = $currentAcl[0];
751 }
753 // Detect configured plugins
754 $expand = count($currentAcl) > 1 || $currentAcl[0] != "";
756 /* Object header */
757 $tname= preg_replace("/[^a-z0-9]/i","_",$name);
759 if($expand){
760 $back_color = "#C8C8FF";
761 }else{
762 $back_color = "#C8C8C8";
763 }
765 if(session::global_get('js')) {
766 if(isset($_SERVER['HTTP_USER_AGENT']) &&
767 (preg_match("/gecko/i",$_SERVER['HTTP_USER_AGENT'])) ||
768 (preg_match("/presto/i",$_SERVER['HTTP_USER_AGENT']))) {
769 $display.= "\n<table style='width:100%;border:1px solid #A0A0A0' cellspacing=0 cellpadding=2>".
770 "\n <tr>".
771 "\n <td style='background-color:{$back_color};height:1.8em;' colspan=".($cols-1)."><b>"._("Object").": $name</b></td>".
772 "\n <td align='right' style='background-color:{$back_color};height:1.8em;'>".
773 "\n <input type='button' onclick='divGOsa_toggle(\"$tname\");' value='"._("Show/hide advanced settings")."' /></td>".
774 "\n </tr>";
775 } else if (isset($_SERVER['HTTP_USER_AGENT']) && preg_match("/ie/i",$_SERVER['HTTP_USER_AGENT'])) {
776 $display.= "\n<table style='width:100%;border:1px solid #A0A0A0' cellspacing=0 cellpadding=2>".
777 "\n <tr>".
778 "\n <td style='background-color:#C8C8C8;height:1.8em;' colspan=".($cols-1)."><b>"._("Object").": $name</b></td>".
779 "\n <td align='right' style='background-color:#C8C8C8;height:1.8em;'>".
780 "\n <input type='button' onclick='divGOsa_toggle(\"$tname\");' value='"._("Show/hide advanced settings")."' /></td>".
781 "\n </tr>";
782 } else {
783 $display.= "\n<table style='width:100%;border:1px solid #A0A0A0' cellspacing=0 cellpadding=2>".
784 "\n <tr>".
785 "\n <td style='background-color:#C8C8C8;height:1.8em;' colspan=$cols><b>"._("Object").": $name</b></td>".
786 "\n </tr>";
787 }
788 } else {
789 $display.= "\n<table style='width:100%;border:1px solid #A0A0A0' cellspacing=0 cellpadding=2>".
790 "\n <tr>".
791 "\n <td style='background-color:#C8C8C8;height:1.8em;' colspan=$cols><b>"._("Object").": $name</b></td>".
792 "\n </tr>";
793 }
795 /* Generate options */
796 $spc= " ";
797 $options= $this->mkchkbx($key."_0_c", _("Create objects"), preg_match('/c/', $overall_acl)).$spc;
798 $options.= $this->mkchkbx($key."_0_m", _("Move objects"), preg_match('/m/', $overall_acl)).$spc;
799 $options.= $this->mkchkbx($key."_0_d", _("Remove objects"), preg_match('/d/', $overall_acl)).$spc;
800 if ($plist[preg_replace('%^.*/%', '', $key)]['plSelfModify']){
801 $options.= $this->mkchkbx($key."_0_s", _("Grant permission to owner"), preg_match('/s/', $overall_acl)).$spc;
802 }
804 /* Global options */
805 $more_options= $this->mkchkbx($key."_0_r", _("read"), preg_match('/r/', $overall_acl)).$spc;
806 $more_options.= $this->mkchkbx($key."_0_w", _("write"), preg_match('/w/', $overall_acl));
808 $display.= "\n <tr>".
809 "\n <td style='background-color:#E0E0E0' colspan=".($cols-1).">$options</td>".
810 "\n <td style='background-color:#D4D4D4'> "._("Complete object").": $more_options</td>".
811 "\n </tr>";
813 /* Walk through the list of attributes */
814 $cnt= 1;
815 $splist= $plist[preg_replace('%^.*/%', '', $key)]['plProvidedAcls'];
816 if(session::global_get('js')) {
817 if(isset($_SERVER['HTTP_USER_AGENT']) &&
818 (preg_match("/gecko/i",$_SERVER['HTTP_USER_AGENT'])) || (preg_match("/presto/i",$_SERVER['HTTP_USER_AGENT']))) {
819 $display.= "\n <tr id='tr_$tname' style='vertical-align:top;height:0px;'>".
820 "\n <td colspan=".$cols.">".
821 "\n <div id='$tname' style='overflow:hidden;visibility:hidden;height:0px;vertical-align:top;width:100%;'>".
822 "\n <table style='width:100%;'>";
823 } else if (isset($_SERVER['HTTP_USER_AGENT']) && preg_match("/ie/i",$_SERVER['HTTP_USER_AGENT'])) {
824 $display.= "\n <tr id='tr_$tname' style='vertical-align:top;height:0px;'>".
825 "\n <td colspan=".$cols.">".
826 "\n <div id='$tname' style='position:absolute;overflow:hidden;visibility:hidden;height:0px;vertical-align:top;width:100%;'>".
827 "\n <table style='width:100%;'>";
828 }else{
829 }
830 }
833 foreach($splist as $attr => $dsc){
835 /* Skip pl* attributes, they are internal... */
836 if (preg_match('/^pl[A-Z]+.*$/', $attr)){
837 continue;
838 }
840 /* Open table row */
841 if ($cnt == 1){
842 $display.= "\n <tr>";
843 }
845 /* Close table row */
846 if ($cnt == $cols){
847 $cnt= 1;
848 $rb= "";
849 $end= "\n </tr>";
850 } else {
851 $cnt++;
852 $rb= "border-right:1px solid #A0A0A0;";
853 $end= "";
854 }
856 /* Collect list of attributes */
857 $state= "";
858 if (isset($currentAcl[$attr])){
859 $state= $currentAcl[$attr];
860 }
861 $display.= "\n <td style='border-top:1px solid #A0A0A0;${rb}width:".(int)(100/$cols)."%'>".
862 "\n <b>$dsc</b> ($attr)<br>".$this->mkrwbx($key."_".$attr, $state)."</td>$end";
863 }
865 /* Fill missing td's if needed */
866 if (--$cnt != $cols && $cnt != 0){
867 $display.= str_repeat("\n <td style='border-top:1px solid #A0A0A0; width:".(int)(100/$cols)."%'> </td>", $cols-$cnt);
868 }
870 if(session::global_get('js')) {
871 if(isset($_SERVER['HTTP_USER_AGENT']) &&
872 (preg_match("/gecko/i",$_SERVER['HTTP_USER_AGENT'])) ||
873 (preg_match("/presto/i",$_SERVER['HTTP_USER_AGENT'])) ||
874 (preg_match("/ie/i",$_SERVER['HTTP_USER_AGENT']))) {
875 $display.= "\n </table>".
876 "\n </div>".
877 "\n </td>".
878 "\n </tr>";
879 }
880 }
882 $display.= "\n</table><br />\n";
883 }
885 return ($display);
886 }
889 function mkchkbx($name, $text, $state= FALSE)
890 {
891 $state= $state?"checked":"";
892 if($this->acl_is_writeable("")){
893 $tname= preg_replace("/[^a-z0-9]/i","_",$name);
894 return "\n <input id='acl_$tname' type=checkbox name='acl_$name' $state>".
895 "\n <label for='acl_$tname'>$text</label>";
896 }else{
897 return "\n <input type='checkbox' disabled name='dummy_".microtime(1)."' $state>$text";
898 }
899 }
902 function mkrwbx($name, $state= "")
903 {
904 $rstate= preg_match('/r/', $state)?'checked':'';
905 $wstate= preg_match('/w/', $state)?'checked':'';
906 $tname= preg_replace("/[^a-z0-9]/i","_",$name);
908 if($this->acl_is_writeable("")){
909 return ("\n <input id='acl_".$tname."_r' type=checkbox name='acl_${name}_r' $rstate>".
910 "\n <label for='acl_".$tname."_r'>"._("read")."</label>".
911 "\n <input id='acl_".$tname."_w' type=checkbox name='acl_${name}_w' $wstate>".
912 "\n <label for='acl_".$tname."_w'>"._("write")."</label>");
913 }else{
914 return ("\n <input disabled type=checkbox name='dummy_".microtime(1)."' $rstate>"._("read").
915 "\n <input disabled type=checkbox name='dummy_".microtime(1)."' $wstate>"._("write"));
916 }
917 }
920 static function explodeACL($acl)
921 {
923 $list= split(':', $acl);
924 if(count($list) == 5){
925 list($index, $type,$member,$permission,$filter)= $list;
926 $filter = base64_decode($filter);
927 }else{
928 $filter = "";
929 list($index, $type,$member,$permission)= $list;
930 }
932 $a= array( $index => array("type" => $type,
933 "filter"=> $filter,
934 "members" => acl::extractMembers($acl,$type == "role")));
936 /* Handle different types */
937 switch ($type){
939 case 'psub':
940 case 'sub':
941 case 'one':
942 case 'base':
943 $a[$index]['acl']= acl::extractACL($acl);
944 break;
946 case 'role':
947 $a[$index]['acl']= base64_decode(preg_replace('/^[^:]+:[^:]+:([^:]+).*$/', '\1', $acl));
948 break;
950 case 'reset':
951 break;
953 default:
954 msg_dialog::display(_("Internal error"), sprintf(_("Unkown ACL type '%s'!"), $type), ERROR_DIALOG);
955 $a= array();
956 }
957 return ($a);
958 }
961 static function extractMembers($acl,$role = FALSE)
962 {
963 global $config;
964 $a= array();
966 /* Rip acl off the string, seperate by ',' and place it in an array */
967 if($role){
968 $ms= preg_replace('/^[^:]+:[^:]+:[^:]+:([^:]+).*$/', '\1', $acl);
969 }else{
970 $ms= preg_replace('/^[^:]+:[^:]+:([^:]+).*$/', '\1', $acl);
971 }
972 if ($ms == $acl){
973 return $a;
974 }
975 $ma= split(',', $ms);
977 /* Decode dn's, fill with informations from LDAP */
978 $ldap= $config->get_ldap_link();
979 foreach ($ma as $memberdn){
980 $dn= base64_decode($memberdn);
981 $ldap->cat($dn, array('cn', 'objectClass', 'description', 'uid'));
983 /* Found entry... */
984 if ($ldap->count()){
985 $attrs= $ldap->fetch();
986 if (in_array_ics('gosaAccount', $attrs['objectClass'])){
987 $a['U:'.$dn]= $attrs['cn'][0]." [".$attrs['uid'][0]."]";
988 } else {
989 $a['G:'.$dn]= $attrs['cn'][0];
990 if (isset($attrs['description'][0])){
991 $a['G:'.$dn].= " [".$attrs['description'][0]."]";
992 }
993 }
995 /* ... or not */
996 } else {
997 $a['U:'.$dn]= sprintf(_("Unknown entry '%s'!"), $dn);
998 }
999 }
1001 return ($a);
1002 }
1005 static function extractACL($acl)
1006 {
1007 /* Rip acl off the string, seperate by ',' and place it in an array */
1008 $as= preg_replace('/^[^:]+:[^:]+:[^:]*:([^:]*).*$/', '\1', $acl);
1009 $aa= split(',', $as);
1010 $a= array();
1012 /* Dis-assemble single ACLs */
1013 foreach($aa as $sacl){
1015 /* Dis-assemble field ACLs */
1016 $ao= split('#', $sacl);
1017 $gobject= "";
1018 foreach($ao as $idx => $ssacl){
1020 /* First is department with global acl */
1021 $object= preg_replace('/^([^;]+);.*$/', '\1', $ssacl);
1022 $gacl= preg_replace('/^[^;]+;(.*)$/', '\1', $ssacl);
1023 if ($idx == 0){
1024 /* Create hash for this object */
1025 $gobject= $object;
1026 $a[$gobject]= array();
1028 /* Append ACL if set */
1029 if ($gacl != ""){
1030 $a[$gobject]= array($gacl);
1031 }
1032 } else {
1034 /* All other entries get appended... */
1035 list($field, $facl)= split(';', $ssacl);
1036 $a[$gobject][$field]= $facl;
1037 }
1039 }
1040 }
1042 return ($a);
1043 }
1046 function assembleAclSummary($entry)
1047 {
1048 $summary= "";
1050 /* Summarize ACL */
1051 if (isset($entry['acl'])){
1052 $acl= "";
1054 if($entry['type'] == "role"){
1056 if(isset($this->roles[$entry['acl']])){
1057 $summary.= sprintf(_("Role: %s"), $this->roles[$entry['acl']]['cn']);
1058 }else{
1059 $summary.= sprintf(_("Role: %s"), "<i>"._("unknown role")."</i>");
1060 }
1061 }else{
1062 foreach ($entry['acl'] as $name => $object){
1063 if (count($object)){
1064 $acl.= "$name, ";
1065 }
1066 }
1067 $summary.= sprintf(_("Contains settings for these objects: %s"), preg_replace('/, $/', '', $acl));
1068 }
1069 }
1072 /* Summarize members */
1073 if(!($this instanceOf aclrole)){
1074 if ($summary != ""){
1075 $summary.= ", ";
1076 }
1077 if (count($entry['members'])){
1078 $summary.= _("Members").": ";
1079 foreach ($entry['members'] as $cn){
1080 $cn= preg_replace('/ \[.*$/', '', $cn);
1081 $summary.= $cn.", ";
1082 }
1083 } else {
1084 $summary.= "<font color='red'><i>"._("inactive")." - "._("No members")."</i></font>";
1085 }
1086 }
1087 return (preg_replace('/, $/', '', $summary));
1088 }
1091 function loadAclEntry($new= FALSE)
1092 {
1093 /* New entry gets presets... */
1094 if ($new){
1095 $this->aclType= 'base';
1096 $this->aclFilter= "";
1097 $this->recipients= array();
1098 $this->aclContents= array();
1099 } else {
1100 $acl= $this->gosaAclEntry[$this->currentIndex];
1101 $this->aclType= $acl['type'];
1102 $this->recipients= $acl['members'];
1103 $this->aclContents= $acl['acl'];
1104 $this->aclFilter= $acl['filter'];
1105 }
1107 $this->wasNewEntry= $new;
1108 }
1111 function aclPostHandler()
1112 {
1113 if (isset($_POST['save_acl'])){
1114 $this->save();
1115 return TRUE;
1116 }
1118 return FALSE;
1119 }
1122 function PrepareForCopyPaste($source)
1123 {
1124 plugin::PrepareForCopyPaste($source);
1126 $dn = $source['dn'];
1127 $acl_c = new acl($this->config, $this->parent,$dn);
1128 $this->gosaAclEntry = $acl_c->gosaAclEntry;
1129 }
1132 function save()
1133 {
1134 /* Assemble ACL's */
1135 $tmp_acl= array();
1137 foreach ($this->gosaAclEntry as $prio => $entry){
1138 $final= "";
1139 $members= "";
1140 if (isset($entry['members'])){
1141 foreach ($entry['members'] as $key => $dummy){
1142 $members.= base64_encode(preg_replace('/^.:/', '', $key)).',';
1143 }
1144 }
1146 if($entry['type'] != "role"){
1147 $final= $prio.":".$entry['type'].":".preg_replace('/,$/', '', $members);
1148 }else{
1149 $final= $prio.":".$entry['type'].":".base64_encode($entry['acl']).":".preg_replace('/,$/', '', $members);
1150 }
1152 /* ACL's if needed */
1153 if ($entry['type'] != "reset" && $entry['type'] != "role"){
1154 $acl= ":";
1155 if (isset($entry['acl'])){
1156 foreach ($entry['acl'] as $object => $contents){
1158 /* Only save, if we've some contents in there... */
1159 if (count($contents)){
1160 $acl.= $object.";";
1162 foreach($contents as $attr => $permission){
1164 /* First entry? Its the one for global settings... */
1165 if ($attr == '0'){
1166 $acl.= $permission;
1167 } else {
1168 $acl.= '#'.$attr.';'.$permission;
1169 }
1171 }
1172 $acl.= ',';
1173 }
1175 }
1176 }
1177 $final.= preg_replace('/,$/', '', $acl);
1178 }
1180 /* Append additional filter options
1181 */
1182 if(!empty($entry['filter'])){
1183 $final .= ":".base64_encode($entry['filter']);
1184 }
1186 $tmp_acl[]= $final;
1187 }
1189 /* Call main method */
1190 plugin::save();
1192 /* Finally (re-)assign it... */
1193 $this->attrs['gosaAclEntry']= $tmp_acl;
1195 /* Remove acl from this entry if it is empty... */
1196 if (!count($tmp_acl)){
1197 /* Remove attribute */
1198 if ($this->initially_was_account){
1199 $this->attrs['gosaAclEntry']= array();
1200 } else {
1201 if (isset($this->attrs['gosaAclEntry'])){
1202 unset($this->attrs['gosaAclEntry']);
1203 }
1204 }
1206 /* Remove object class */
1207 $this->attrs['objectClass']= array_remove_entries(array('gosaAcl'), $this->attrs['objectClass']);
1208 }
1210 /* Do LDAP modifications */
1211 $ldap= $this->config->get_ldap_link();
1212 $ldap->cd($this->dn);
1213 $this->cleanup();
1214 $ldap->modify ($this->attrs);
1216 if(count($this->attrs)){
1217 new log("modify","acls/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
1218 }
1220 if (!$ldap->success()){
1221 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_MOD, get_class()), ERROR_DIALOG);
1222 }
1224 /* Refresh users ACLs */
1225 $ui= get_userinfo();
1226 $ui->loadACL();
1227 session::global_set('ui',$ui);
1228 }
1231 function remove_from_parent()
1232 {
1233 plugin::remove_from_parent();
1235 /* include global link_info */
1236 $ldap= $this->config->get_ldap_link();
1238 $ldap->cd($this->dn);
1239 $this->cleanup();
1240 $ldap->modify ($this->attrs);
1242 new log("remove","acls/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
1244 /* Optionally execute a command after we're done */
1245 $this->handle_post_events("remove",array("uid" => $this->uid));
1246 }
1249 /* Return plugin informations for acl handling */
1250 static function plInfo()
1251 {
1252 return (array(
1253 "plShortName" => _("ACL"),
1254 "plDescription" => _("ACL")." ("._("Access control list").")",
1255 "plSelfModify" => FALSE,
1256 "plDepends" => array(),
1257 "plPriority" => 0,
1258 "plSection" => array("administration"),
1259 "plCategory" => array("acl" => array("description" => _("ACL")." & "._("ACL roles"),
1260 "objectClass" => array("gosaAcl","gosaRole"))),
1261 "plProvidedAcls"=> array(
1262 // "cn" => _("Role name"),
1263 // "description" => _("Role description")
1264 )
1266 ));
1267 }
1270 /* Remove acls defined for $src */
1271 function remove_acl()
1272 {
1273 acl::remove_acl_for($this->dn);
1274 }
1277 /* Remove acls defined for $src */
1278 static function remove_acl_for($dn)
1279 {
1280 global $config;
1282 $ldap = $config->get_ldap_link();
1283 $ldap->cd($config->current['BASE']);
1284 $ldap->search("(&(objectClass=gosaAcl)(gosaAclEntry=*".base64_encode($dn)."*))",array("gosaAclEntry","dn"));
1285 $new_entries= array();
1286 while($attrs = $ldap->fetch()){
1287 if (!isset($attrs['gosaAclEntry'])) {
1288 continue;
1289 }
1290 unset($attrs['gosaAclEntry']['count']);
1292 // Remove entry directly
1293 foreach($attrs['gosaAclEntry'] as $id => $entry){
1294 $parts= split(':',$entry);
1295 $members= split(',',$parts[2]);
1296 $new_members= array();
1297 foreach($members as $member) {
1298 if (base64_decode($member) != $dn) {
1299 $new_members[]= $member;
1300 } else {
1301 gosa_log("modify","users/acl",$attrs['dn'],array(),sprintf("Removed acl for %s on object %s.",$dn,$attrs['dn']));
1302 }
1303 }
1305 /* We can completely remove the entry if there are no members anymore */
1306 if (count($new_members)) {
1307 $parts[2]= implode(",", $new_members);
1308 $new_entries[]= implode(":", $parts);
1309 }
1310 }
1312 // There should be a modification, so write it back
1313 $ldap->cd($attrs['dn']);
1314 $new_attrs= array("gosaAclEntry" => $new_entries);
1315 $ldap->modify($new_attrs);
1316 if (!$ldap->success()){
1317 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_MOD, get_class()), ERROR_DIALOG);
1318 }
1319 }
1320 }
1323 function update_acl_membership($src,$dst)
1324 {
1325 $ldap = $this->config->get_ldap_link();
1326 $ldap->cd($this->config->current['BASE']);
1327 $ldap->search("(&(objectClass=gosaAcl)(gosaAclEntry=*".base64_encode($src)."*))",array("gosaAclEntry","dn"));
1328 while($attrs = $ldap->fetch()){
1329 $acl = new acl($this->config,$this->parent,$attrs['dn']);
1330 foreach($acl->gosaAclEntry as $id => $entry){
1331 foreach($entry['members'] as $m_id => $member){
1332 if($m_id == "U:".$src){
1333 unset($acl->gosaAclEntry[$id]['members'][$m_id]);
1334 $new = "U:".$dst;
1335 $acl->gosaAclEntry[$id]['members'][$new] = $new;
1336 gosa_log("modify","users/acl",$attrs['dn'],array(),sprintf("Updated acl for user %s on object %s.",$src,$attrs['dn']));
1337 }
1338 if($m_id == "G:".$src){
1339 unset($acl->gosaAclEntry[$id]['members'][$m_id]);
1340 $new = "G:".$dst;
1341 $acl->gosaAclEntry[$id]['members'][$new] = $new;
1342 gosa_log("modify","groups/acl",$attrs['dn'],array(),sprintf("Updated acl for group %s on object %s.",$src,$attrs['dn']));
1343 }
1344 }
1345 }
1346 $acl -> save();
1347 }
1348 }
1350 }
1352 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1353 ?>