1 <?php
3 class aclrole extends plugin
4 {
5 /* Definitions */
6 var $plHeadline= "Access control list templates";
7 var $plDescription= "This does something";
9 /* attribute list for save action */
10 var $attributes= array('gosaAclTemplate',"cn","description");
11 var $objectclasses= array('top','gosaRole');
13 /* Helpers */
14 var $dialogState= "head";
15 var $aclType= "";
16 var $aclObject= "";
17 var $aclContents= array();
18 var $target= "group";
19 var $aclTypes= array();
20 var $aclObjects= array();
21 var $recipients= array();
22 var $isContainer= TRUE;
23 var $currentIndex= 0;
24 var $wasNewEntry= FALSE;
25 var $ocMapping= array();
26 var $savedAclContents= array();
27 var $myAclObjects = array();
29 /* Role attributes */
30 var $gosaAclTemplate= "";
31 var $cn = "";
32 var $description = "";
33 var $orig_dn;
34 var $base ="";
36 function aclrole ($config, $dn= NULL)
37 {
38 /* Include config object */
39 plugin::plugin($config, $dn);
41 if($this->dn == "new"){
42 $this->base = $_SESSION['CurrentMainBase'];
43 }else{
44 $this->base = preg_replace("/^[^,]+,[^,]+,/","",$this->dn);
45 }
47 /* Load ACL's */
48 $this->gosaAclTemplate= array();
49 if (isset($this->attrs["gosaAclTemplate"])){
50 for ($i= 0; $i<$this->attrs["gosaAclTemplate"]['count']; $i++){
51 $acl= $this->attrs["gosaAclTemplate"][$i];
52 $this->gosaAclTemplate= array_merge($this->gosaAclTemplate, $this->explodeACL($acl));
53 }
54 }
55 ksort($this->gosaAclTemplate);
57 /* Extract available categories from plugin info list */
58 $tmp= get_global('plist');
59 $plist= $tmp->info;
60 $oc = array();
61 foreach ($plist as $class => $acls){
63 /* Only feed categories */
64 if (isset($acls['plCategory'])){
66 /* Walk through supplied list and feed only translated categories */
67 foreach($acls['plCategory'] as $idx => $data){
69 /* Non numeric index means -> base object containing more informations */
70 if (preg_match('/^[0-9]+$/', $idx)){
71 if (!isset($this->ocMapping[$data])){
72 $this->ocMapping[$data]= array();
73 $this->ocMapping[$data][]= '0';
74 }
75 $this->ocMapping[$data][]= $class;
76 } else {
77 if (!isset($this->ocMapping[$idx])){
78 $this->ocMapping[$idx]= array();
79 $this->ocMapping[$idx][]= '0';
80 }
81 $this->ocMapping[$idx][]= $class;
82 $this->aclObjects[$idx]= $data['description'];
84 /* Additionally filter the classes we're interested in in "self edit" mode */
85 if (is_array($data['objectClass'])){
86 foreach($data['objectClass'] as $objectClass){
87 if (in_array_ics($objectClass, $oc)){
88 $this->myAclObjects[$idx.'/'.$class]= $acls['plDescription'];
89 break;
90 }
91 }
92 } else {
93 if (in_array_ics($data['objectClass'], $oc)){
94 $this->myAclObjects[$idx.'/'.$class]= $acls['plDescription'];
95 }
96 }
97 }
99 }
100 }
101 }
102 $this->aclObjects['all']= '* '._("All categories");
103 $this->ocMapping['all']= array('0' => 'all');
105 /* Sort categories */
106 asort($this->aclObjects);
108 /* Fill acl types */
109 $this->aclTypes= array( "reset" => _("Reset ACLs"),
110 "one" => _("One level"),
111 "base" => _("Current object"),
112 "sub" => _("Complete subtree"),
113 "psub" => _("Complete subtree (permanent)"));
114 asort($this->aclTypes);
116 /* Finally - we want to get saved... */
117 $this->is_account= TRUE;
118 }
121 function execute()
122 {
123 /* Call parent execute */
124 plugin::execute();
126 /* Base select dialog */
127 $once = true;
128 foreach($_POST as $name => $value){
129 if((preg_match("/^chooseBase/",$name) && $once) && ($this->acl_is_moveable())){
130 $once = false;
131 $this->dialog = new baseSelectDialog($this->config,$this,$this->get_allowed_bases());
132 $this->dialog->setCurrentBase($this->base);
133 }
134 }
136 /* Dialog handling */
137 if(is_object($this->dialog)){
138 /* Must be called before save_object */
139 $this->dialog->save_object();
141 if($this->dialog->isClosed()){
142 $this->dialog = false;
143 }elseif($this->dialog->isSelected()){
145 /* Check if selected base is valid */
146 $tmp = $this->get_allowed_bases();
147 if(isset($tmp[$this->dialog->isSelected()])){
148 $this->base = $this->dialog->isSelected();
149 }
150 $this->dialog= false;
151 }else{
152 return($this->dialog->execute());
153 }
154 }
156 $tmp= get_global('plist');
157 $plist= $tmp->info;
159 /* Handle posts */
160 if (isset($_POST['new_acl'])){
161 $this->dialogState= 'create';
162 $this->dialog= TRUE;
163 $this->currentIndex= count($this->gosaAclTemplate);
164 $this->loadAclEntry(TRUE);
165 }
167 $new_acl= array();
168 $aclDialog= FALSE;
169 $firstedit= FALSE;
170 foreach($_POST as $name => $post){
172 /* Actions... */
173 if (preg_match('/^acl_edit_.*_x/', $name)){
174 $this->dialogState= 'create';
175 $firstedit= TRUE;
176 $this->dialog= TRUE;
177 $this->currentIndex= preg_replace('/^acl_edit_([0-9]+).*$/', '\1', $name);
178 $this->loadAclEntry();
179 continue;
180 }
181 if (preg_match('/^acl_del_.*_x/', $name)){
182 unset($this->gosaAclTemplate[preg_replace('/^acl_del_([0-9]+).*$/', '\1', $name)]);
183 continue;
184 }
186 if (preg_match('/^cat_edit_.*_x/', $name)){
187 $this->aclObject= preg_replace('/^cat_edit_([^_]+)_.*$/', '\1', $name);
188 $this->dialogState= 'edit';
189 foreach ($this->ocMapping[$this->aclObject] as $oc){
190 if (isset($this->aclContents[$oc])){
191 $this->savedAclContents[$oc]= $this->aclContents[$oc];
192 }
193 }
194 continue;
195 }
196 if (preg_match('/^cat_del_.*_x/', $name)){
197 $idx= preg_replace('/^cat_del_([^_]+)_.*$/', '\1', $name);
198 foreach ($this->ocMapping[$idx] as $key){
199 unset($this->aclContents["$idx/$key"]);
200 }
201 continue;
202 }
204 /* Sorting... */
205 if (preg_match('/^sortup_.*_x/', $name)){
206 $index= preg_replace('/^sortup_([0-9]+).*$/', '\1', $name);
207 if ($index > 0){
208 $tmp= $this->gosaAclTemplate[$index];
209 $this->gosaAclTemplate[$index]= $this->gosaAclTemplate[$index-1];
210 $this->gosaAclTemplate[$index-1]= $tmp;
211 }
212 continue;
213 }
214 if (preg_match('/^sortdown_.*_x/', $name)){
215 $index= preg_replace('/^sortdown_([0-9]+).*$/', '\1', $name);
216 if ($index < count($this->gosaAclTemplate)-1){
217 $tmp= $this->gosaAclTemplate[$index];
218 $this->gosaAclTemplate[$index]= $this->gosaAclTemplate[$index+1];
219 $this->gosaAclTemplate[$index+1]= $tmp;
220 }
221 continue;
222 }
224 /* ACL saving... */
225 if (preg_match('/^acl_.*_[^xy]$/', $name)){
226 $aclDialog= TRUE;
227 list($dummy, $object, $attribute, $value)= split('_', $name);
229 /* Skip for detection entry */
230 if ($object == 'dummy') {
231 continue;
232 }
234 /* Ordinary ACLs */
235 if (!isset($new_acl[$object])){
236 $new_acl[$object]= array();
237 }
238 if (isset($new_acl[$object][$attribute])){
239 $new_acl[$object][$attribute].= $value;
240 } else {
241 $new_acl[$object][$attribute]= $value;
242 }
243 }
244 }
246 /* Only be interested in new acl's, if we're in the right _POST place */
247 if ($aclDialog && $this->aclObject != "" && is_array($this->ocMapping[$this->aclObject])){
249 foreach ($this->ocMapping[$this->aclObject] as $oc){
250 unset($this->aclContents[$oc]);
251 unset($this->aclContents[$this->aclObject.'/'.$oc]);
252 if (isset($new_acl[$oc])){
253 $this->aclContents[$oc]= $new_acl[$oc];
254 }
255 if (isset($new_acl[$this->aclObject.'/'.$oc])){
256 $this->aclContents[$this->aclObject.'/'.$oc]= $new_acl[$this->aclObject.'/'.$oc];
257 }
258 }
259 }
261 /* Save new acl in case of base edit mode */
262 if (1 == 0 && $this->aclType == 'base' && !$firstedit){
263 $this->aclContents= $new_acl;
264 }
266 /* Cancel new acl? */
267 if (isset($_POST['cancel_new_acl'])){
268 $this->dialogState= 'head';
269 $this->dialog= FALSE;
270 if ($this->wasNewEntry){
271 unset ($this->gosaAclTemplate[$this->currentIndex]);
272 }
273 }
275 /* Store ACL in main object? */
276 if (isset($_POST['submit_new_acl'])){
277 $this->gosaAclTemplate[$this->currentIndex]['type']= $this->aclType;
278 $this->gosaAclTemplate[$this->currentIndex]['members']= $this->recipients;
279 $this->gosaAclTemplate[$this->currentIndex]['acl']= $this->aclContents;
280 $this->dialogState= 'head';
281 $this->dialog= FALSE;
282 }
284 /* Cancel edit acl? */
285 if (isset($_POST['cancel_edit_acl'])){
286 $this->dialogState= 'create';
287 foreach ($this->ocMapping[$this->aclObject] as $oc){
288 if (isset($this->savedAclContents[$oc])){
289 $this->aclContents[$oc]= $this->savedAclContents[$oc];
290 }
291 }
292 }
294 /* Save edit acl? */
295 if (isset($_POST['submit_edit_acl'])){
296 $this->dialogState= 'create';
297 }
299 /* Add acl? */
300 if (isset($_POST['add_acl']) && $_POST['aclObject'] != ""){
301 $this->dialogState= 'edit';
302 $this->savedAclContents= array();
303 foreach ($this->ocMapping[$this->aclObject] as $oc){
304 if (isset($this->aclContents[$oc])){
305 $this->savedAclContents[$oc]= $this->aclContents[$oc];
306 }
307 }
308 }
310 /* Save common values */
311 foreach (array("aclType", "aclObject", "target") as $key){
312 if (isset($_POST[$key])){
313 $this->$key= validate($_POST[$key]);
314 }
315 }
317 /* Create templating instance */
318 $smarty= get_smarty();
320 $smarty->assign("bases", $this->get_allowed_bases());
321 $smarty->assign("base_select", $this->base);
323 $tmp = $this->plInfo();
324 foreach($tmp['plProvidedAcls'] as $name => $translation){
325 $smarty->assign($name."ACL",$this->getacl($name));
326 }
328 if ($this->dialogState == 'head'){
329 /* Draw list */
330 $aclList= new DivSelectBox("aclList");
331 $aclList->SetHeight(350);
333 /* Fill in entries */
334 foreach ($this->gosaAclTemplate as $key => $entry){
335 $field1= array("string" => $this->aclTypes[$entry['type']], "attach" => "style='width:100px'");
336 $field2= array("string" => $this->assembleAclSummary($entry));
337 $action= "<input type='image' name='sortup_$key' alt='up' title='"._("Up")."' src='images/sort_up.png' align='top'>";
338 $action.= "<input type='image' name='sortdown_$key' alt='down' title='"._("Down")."' src='images/sort_down.png'>";
339 $action.= "<input class='center' type='image' src='images/edit.png' alt='"._("edit")."' name='acl_edit_$key' title='"._("Edit ACL")."'>";
340 $action.= "<input class='center' type='image' src='images/edittrash.png' alt='"._("delete")."' name='acl_del_$key' title='"._("Delete ACL")."'>";
342 $field3= array("string" => $action, "attach" => "style='border-right:0px;width:50px;text-align:right;'");
343 $aclList->AddEntry(array($field1, $field2, $field3));
344 }
346 $smarty->assign("aclList", $aclList->DrawList());
347 }
349 if ($this->dialogState == 'create'){
350 /* Draw list */
351 $aclList= new DivSelectBox("aclList");
352 $aclList->SetHeight(450);
354 /* Add settings for all categories to the (permanent) list */
355 foreach ($this->aclObjects as $section => $dsc){
356 $summary= "";
357 foreach($this->ocMapping[$section] as $oc){
358 if (isset($this->aclContents[$oc]) && count($this->aclContents[$oc]) && isset($this->aclContents[$oc][0]) &&
359 $this->aclContents[$oc][0] != ""){
361 $summary.= "$oc, ";
362 continue;
363 }
364 if (isset($this->aclContents["$section/$oc"]) && count($this->aclContents["$section/$oc"]) && isset($this->aclContents["$section/$oc"][0]) &&
365 $this->aclContents["$section/$oc"][0] != ""){
367 $summary.= "$oc, ";
368 continue;
369 }
370 if (isset($this->aclContents[$oc]) && !isset($this->aclContents[$oc][0]) && count($this->aclContents[$oc])){
371 $summary.= "$oc, ";
372 }
373 }
375 /* Set summary... */
376 if ($summary == ""){
377 $summary= '<i>'._("No ACL settings for this category").'</i>';
378 } else {
379 $summary= sprintf(_("Contains ACLs for these objects: %s"), preg_replace('/, $/', '', $summary));
380 }
382 $field1= array("string" => $dsc, "attach" => "style='width:140px'");
383 $field2= array("string" => $summary);
384 $action= "<input class='center' type='image' src='images/edit.png' alt='"._("edit")."' name='cat_edit_$section' title='"._("Edit categories ACLs")."'>";
385 $action.= "<input class='center' type='image' src='images/edittrash.png' alt='"._("delete")."' name='cat_del_$section' title='"._("Clear categories ACLs")."'>";
386 $field3= array("string" => $action, "attach" => "style='border-right:0px;width:50px'");
387 $aclList->AddEntry(array($field1, $field2, $field3));
388 }
390 $smarty->assign("aclList", $aclList->DrawList());
391 $smarty->assign("aclType", $this->aclType);
392 $smarty->assign("aclTypes", $this->aclTypes);
393 $smarty->assign("target", $this->target);
395 if ($this->aclType == 'base'){
396 $smarty->assign('aclSelector', $this->buildAclSelector($this->myAclObjects));
397 }
398 }
400 if ($this->dialogState == 'edit'){
401 $smarty->assign('headline', sprintf(_("Edit ACL for '%s', scope is '%s'"), $this->aclObjects[$this->aclObject], $this->aclTypes[$this->aclType]));
403 /* Collect objects for selected category */
404 foreach ($this->ocMapping[$this->aclObject] as $idx => $class){
405 if ($idx == 0){
406 continue;
407 }
408 $aclObjects[$this->aclObject.'/'.$class]= $plist[$class]['plDescription'];
409 }
410 if ($this->aclObject == 'all'){
411 $aclObjects['all']= _("All objects in current subtree");
412 }
413 $smarty->assign('aclSelector', $this->buildAclSelector($aclObjects));
414 }
416 /* Show main page */
417 $smarty->assign("dialogState", $this->dialogState);
419 /* Assign cn and decription if this is a role */
420 foreach(array("cn","description") as $name){
421 $smarty->assign($name,$this->$name);
422 }
423 return ($smarty->fetch (get_template_path('acl_role.tpl',dirname(__FILE__))));
424 }
426 function sort_by_priority($list)
427 {
428 $tmp= get_global('plist');
429 $plist= $tmp->info;
430 asort($plist);
431 $newSort = array();
433 foreach($list as $name => $translation){
434 $na = preg_replace("/^.*\//","",$name);
435 $prio= $plist[$na]['plPriority'] ;
437 $newSort[$name] = $prio;
438 }
440 asort($newSort);
442 $ret = array();
443 foreach($newSort as $name => $prio){
444 $ret[$name] = $list[$name];
445 }
446 return($ret);
447 }
449 function buildAclSelector($list)
450 {
451 $display= "<input type='hidden' name='acl_dummy_0_0_0' value='1'>";
452 $cols= 3;
453 $tmp= get_global('plist');
454 $plist= $tmp->info;
455 asort($plist);
457 /* Add select all/none buttons */
458 $style = "style='width:100px;'";
460 $display .= "<input ".$style." type='button' name='toggle_all_create' onClick=\"acl_toggle_all('_0_c$');\" value='Toggle C'>";
461 $display .= "<input ".$style." type='button' name='toggle_all_move' onClick=\"acl_toggle_all('_0_m$');\" value='Toggle M'>";
462 $display .= "<input ".$style." type='button' name='toggle_all_remove' onClick=\"acl_toggle_all('_0_d$');\" value='Toggle D'> - ";
463 $display .= "<input ".$style." type='button' name='toggle_all_read' onClick=\"acl_toggle_all('_0_r$');\" value='Toggle R'>";
464 $display .= "<input ".$style." type='button' name='toggle_all_write' onClick=\"acl_toggle_all('_0_w$');\" value='Toggle W'> - ";
466 $display .= "<input ".$style." type='button' name='toggle_all_sub_read' onClick=\"acl_toggle_all('[^0]_r$');\" value='R+'>";
467 $display .= "<input ".$style." type='button' name='toggle_all_sub_write' onClick=\"acl_toggle_all('[^0]_w$');\" value='W+'>";
469 $display .= "<br>";
471 $style = "style='width:50px;'";
472 $display .= "<input ".$style." type='button' name='set_true_all_create' onClick=\"acl_set_all('_0_c$',true);\" value='C+'>";
473 $display .= "<input ".$style." type='button' name='set_false_all_create' onClick=\"acl_set_all('_0_c$',false);\" value='C-'>";
474 $display .= "<input ".$style." type='button' name='set_true_all_move' onClick=\"acl_set_all('_0_m$',true);\" value='M+'>";
475 $display .= "<input ".$style." type='button' name='set_false_all_move' onClick=\"acl_set_all('_0_m$',false);\" value='M-'>";
476 $display .= "<input ".$style." type='button' name='set_true_all_remove' onClick=\"acl_set_all('_0_d$',true);\" value='D+'>";
477 $display .= "<input ".$style." type='button' name='set_false_all_remove' onClick=\"acl_set_all('_0_d$',false);\" value='D-'> - ";
478 $display .= "<input ".$style." type='button' name='set_true_all_read' onClick=\"acl_set_all('_0_r$',true);\" value='R+'>";
479 $display .= "<input ".$style." type='button' name='set_false_all_read' onClick=\"acl_set_all('_0_r$',false);\" value='R-'>";
480 $display .= "<input ".$style." type='button' name='set_true_all_write' onClick=\"acl_set_all('_0_w$',true);\" value='W+'>";
481 $display .= "<input ".$style." type='button' name='set_false_all_write' onClick=\"acl_set_all('_0_w$',false);\" value='W-'> - ";
483 $display .= "<input ".$style." type='button' name='set_true_all_read' onClick=\"acl_set_all('[^0]_r$',true);\" value='R+'>";
484 $display .= "<input ".$style." type='button' name='set_false_all_read' onClick=\"acl_set_all('[^0]_r$',false);\" value='R-'>";
485 $display .= "<input ".$style." type='button' name='set_true_all_write' onClick=\"acl_set_all('[^0]_w$',true);\" value='W+'>";
486 $display .= "<input ".$style." type='button' name='set_false_all_write' onClick=\"acl_set_all('[^0]_w$',false);\" value='W-'>";
488 /* Build general objects */
489 $list =$this->sort_by_priority($list);
490 foreach ($list as $key => $name){
492 /* Create sub acl if it does not exist */
493 if (!isset($this->aclContents[$key])){
494 $this->aclContents[$key]= array();
495 $this->aclContents[$key][0]= '';
496 }
497 $currentAcl= $this->aclContents[$key];
499 /* Object header */
500 if($_SESSION['js']) {
501 if(isset($_SERVER['HTTP_USER_AGENT']) && preg_match("/gecko/i",$_SERVER['HTTP_USER_AGENT'])) {
502 $display.= "\n<table style='width:100%;border:1px solid #A0A0A0' cellspacing=0 cellpadding=2>".
503 "\n <tr>".
504 "\n <td style='background-color:#C8C8C8;height:1.8em;' colspan=".($cols-1)."><b>"._("Object").": $name</b></td>".
505 "\n <td align='right' style='background-color:#C8C8C8;height:1.8em;'>".
506 "\n <input type='button' onclick='divtoggle(\"".preg_replace("/[^a-z0-9]/i","_",$name)."\");' value='"._("Show/Hide Advanced Settings")."' /></td>".
507 "\n </tr>";
508 } else if (isset($_SERVER['HTTP_USER_AGENT']) && preg_match("/ie/i",$_SERVER['HTTP_USER_AGENT'])) {
509 $display.= "\n<table style='width:100%;border:1px solid #A0A0A0' cellspacing=0 cellpadding=2>".
510 "\n <tr>".
511 "\n <td style='background-color:#C8C8C8;height:1.8em;' colspan=".($cols-1)."><b>"._("Object").": $name</b></td>".
512 "\n <td align='right' style='background-color:#C8C8C8;height:1.8em;'>".
513 "\n <input type='button' onclick='divtoggle(\"".preg_replace("/[^a-z0-9]/i","_",$name)."\");' value='"._("Show/Hide Advanced Settings")."' /></td>".
514 "\n </tr>";
515 } else {
516 $display.= "\n<table style='width:100%;border:1px solid #A0A0A0' cellspacing=0 cellpadding=2>".
517 "\n <tr>".
518 "\n <td style='background-color:#C8C8C8;height:1.8em;' colspan=$cols><b>"._("Object").": $name</b></td>".
519 "\n </tr>";
520 }
521 } else {
522 $display.= "\n<table style='width:100%;border:1px solid #A0A0A0' cellspacing=0 cellpadding=2>".
523 "\n <tr>".
524 "\n <td style='background-color:#C8C8C8;height:1.8em;' colspan=$cols><b>"._("Object").": $name</b></td>".
525 "\n </tr>";
526 }
528 /* Generate options */
529 $spc= " ";
530 if ($this->isContainer && $this->aclType != 'base'){
531 $options= $this->mkchkbx($key."_0_c", _("Create objects"), preg_match('/c/', $currentAcl[0])).$spc;
532 $options.= $this->mkchkbx($key."_0_m", _("Move objects"), preg_match('/m/', $currentAcl[0])).$spc;
533 $options.= $this->mkchkbx($key."_0_d", _("Remove objects"), preg_match('/d/', $currentAcl[0])).$spc;
534 if ($plist[preg_replace('%^.*/%', '', $key)]['plSelfModify']){
535 $options.= $this->mkchkbx($key."_0_s", _("Modifyable by owner"), preg_match('/s/', $currentAcl[0])).$spc;
536 }
537 } else {
538 $options= $this->mkchkbx($key."_0_m", _("Move object"), preg_match('/m/', $currentAcl[0])).$spc;
539 $options.= $this->mkchkbx($key."_0_d", _("Remove object"), preg_match('/d/', $currentAcl[0])).$spc;
540 if ($plist[preg_replace('%^.*/%', '', $key)]['plSelfModify']){
541 $options.= $this->mkchkbx($key."_0_s", _("Modifyable by owner"), preg_match('/s/', $currentAcl[0])).$spc;
542 }
543 }
545 /* Global options */
546 $more_options= $this->mkchkbx($key."_0_r", _("read"), preg_match('/r/', $currentAcl[0])).$spc;
547 $more_options.= $this->mkchkbx($key."_0_w", _("write"), preg_match('/w/', $currentAcl[0]));
549 $display.= "\n <tr>".
550 "\n <td style='background-color:#E0E0E0' colspan=".($cols-1).">$options</td>".
551 "\n <td style='background-color:#D4D4D4'> "._("Complete object").": $more_options</td>".
552 "\n </tr>";
554 /* Walk through the list of attributes */
555 $cnt= 1;
556 $splist= $plist[preg_replace('%^.*/%', '', $key)]['plProvidedAcls'];
557 asort($splist);
558 if($_SESSION['js']) {
559 if(isset($_SERVER['HTTP_USER_AGENT']) && preg_match("/gecko/i",$_SERVER['HTTP_USER_AGENT'])) {
560 $display.= "\n <tr id='tr_".preg_replace("/[^a-z0-9]/i","_",$name)."' style='vertical-align:top;height:0px;'>".
561 "\n <td colspan=".$cols.">".
562 "\n <div id='".preg_replace("/[^a-z0-9]/i","_",$name)."' style='overflow:hidden;visibility:hidden;height:0px;vertical-align:top;width:100%;'>".
563 "\n <table style='width:100%;'>";
564 } else if (isset($_SERVER['HTTP_USER_AGENT']) && preg_match("/ie/i",$_SERVER['HTTP_USER_AGENT'])) {
565 $display.= "\n <tr id='tr_".preg_replace("/[^a-z0-9]/i","_",$name)."' style='vertical-align:top;height:0px;'>".
566 "\n <td colspan=".$cols.">".
567 "\n <div id='".preg_replace("/[^a-z0-9]/i","_",$name)."' style='position:absolute;overflow:hidden;visibility:hidden;height:0px;vertical-align:top;width:100%;'>".
568 "\n <table style='width:100%;'>";
569 }
570 }
571 foreach($splist as $attr => $dsc){
573 /* Skip pl* attributes, they are internal... */
574 if (preg_match('/^pl[A-Z]+.*$/', $attr)){
575 continue;
576 }
578 /* Open table row */
579 if ($cnt == 1){
580 $display.= "\n <tr>";
581 }
583 /* Close table row */
584 if ($cnt == $cols){
585 $cnt= 1;
586 $rb= "";
587 $end= "\n </tr>";
588 } else {
589 $cnt++;
590 $rb= "border-right:1px solid #A0A0A0;";
591 $end= "";
592 }
594 /* Collect list of attributes */
595 $state= "";
596 if (isset($currentAcl[$attr])){
597 $state= $currentAcl[$attr];
598 }
599 $display.= "\n <td style='border-top:1px solid #A0A0A0;${rb}width:".(int)(100/$cols)."%'>".
600 "\n <b>$dsc</b> ($attr)<br>".$this->mkrwbx($key."_".$attr, $state)."</td>$end";
601 }
603 /* Fill missing td's if needed */
604 if (--$cnt != $cols && $cnt != 0){
605 $display.= str_repeat("\n <td style='border-top:1px solid #A0A0A0; width:".(int)(100/$cols)."%'> </td>", $cols-$cnt);
606 }
608 if($_SESSION['js']) {
609 if(isset($_SERVER['HTTP_USER_AGENT']) && (preg_match("/gecko/i",$_SERVER['HTTP_USER_AGENT'])) || (preg_match("/ie/i",$_SERVER['HTTP_USER_AGENT']))) {
610 $display.= "\n </table>".
611 "\n </div>".
612 "\n </td>".
613 "\n </tr>";
614 }
615 }
617 $display.= "\n</table><br />\n";
618 }
620 return ($display);
621 }
624 function mkchkbx($name, $text, $state= FALSE)
625 {
626 $state= $state?"checked":"";
627 return "\n <input id='acl_".preg_replace("/[^a-z0-9]/i","_",$name)."' type=checkbox name='acl_$name' $state>".
628 "\n <label for='acl_".preg_replace("/[^a-z0-9]/i","_",$name)."'>$text</label>";
629 }
632 function mkrwbx($name, $state= "")
633 {
634 $rstate= preg_match('/r/', $state)?'checked':'';
635 $wstate= preg_match('/w/', $state)?'checked':'';
636 return ("\n <input id='acl_".preg_replace("/[^a-z0-9]/i","_",$name)."_r' type=checkbox name='acl_${name}_r' $rstate>".
637 "\n <label for='acl_".preg_replace("/[^a-z0-9]/i","_",$name)."_r'>"._("read")."</label>".
638 "\n <input id='acl_".preg_replace("/[^a-z0-9]/i","_",$name)."_w' type=checkbox name='acl_${name}_w' $wstate>".
639 "\n <label for='acl_".preg_replace("/[^a-z0-9]/i","_",$name)."_w'>"._("write")."</label>");
640 }
643 function explodeACL($acl)
644 {
645 list($index, $type)= split(':', $acl);
646 $a= array( $index => array("type" => $type,
647 "members" => $this->extractMembers($acl)));
649 /* Handle different types */
650 switch ($type){
652 case 'psub':
653 case 'sub':
654 case 'one':
655 case 'base':
656 $a[$index]['acl']= $this->extractACL($acl);
657 break;
659 case 'role':
660 echo "Role";
661 break;
663 case 'reset':
664 break;
666 default:
667 print_red(sprintf(_("Unkown ACL type '%s'. Don't know how to handle it."), $type));
668 $a= array();
669 }
671 return ($a);
672 }
675 function extractMembers($acl)
676 {
677 global $config;
678 $a= array();
680 /* Rip acl off the string, seperate by ',' and place it in an array */
681 $ms= preg_replace('/^[^:]+:[^:]+:([^:]+).*$/', '\1', $acl);
682 if ($ms == $acl){
683 return $a;
684 }
685 $ma= split(',', $ms);
687 /* Decode dn's, fill with informations from LDAP */
688 $ldap= $config->get_ldap_link();
689 foreach ($ma as $memberdn){
690 $dn= base64_decode($memberdn);
691 $ldap->cat($dn, array('cn', 'objectClass', 'description', 'uid'));
693 /* Found entry... */
694 if ($ldap->count()){
695 $attrs= $ldap->fetch();
696 if (in_array_ics('gosaAccount', $attrs['objectClass'])){
697 $a['U:'.$dn]= $attrs['cn'][0]." [".$attrs['uid'][0]."]";
698 } else {
699 $a['G:'.$dn]= $attrs['cn'][0];
700 if (isset($attrs['description'][0])){
701 $a['G:'.$dn].= " [".$attrs['description'][0]."]";
702 }
703 }
705 /* ... or not */
706 } else {
707 $a['U:'.$dn]= sprintf(_("Unknown entry '%s'!"), $dn);
708 }
709 }
711 return ($a);
712 }
715 function extractACL($acl)
716 {
717 /* Rip acl off the string, seperate by ',' and place it in an array */
718 $as= preg_replace('/^[^:]+:[^:]+:[^:]*:(.*)$/', '\1', $acl);
719 $aa= split(',', $as);
720 $a= array();
722 /* Dis-assemble single ACLs */
723 foreach($aa as $sacl){
725 /* Dis-assemble field ACLs */
726 $ao= split('#', $sacl);
727 $gobject= "";
728 foreach($ao as $idx => $ssacl){
730 /* First is department with global acl */
731 $object= preg_replace('/^([^;]+);.*$/', '\1', $ssacl);
732 $gacl= preg_replace('/^[^;]+;(.*)$/', '\1', $ssacl);
733 if ($idx == 0){
734 /* Create hash for this object */
735 $gobject= $object;
736 $a[$gobject]= array();
738 /* Append ACL if set */
739 if ($gacl != ""){
740 $a[$gobject]= array($gacl);
741 }
742 } else {
744 /* All other entries get appended... */
745 list($field, $facl)= split(';', $ssacl);
746 $a[$gobject][$field]= $facl;
747 }
749 }
750 }
752 return ($a);
753 }
756 function assembleAclSummary($entry)
757 {
758 $summary= "";
760 /* Summarize ACL */
761 if (isset($entry['acl'])){
762 $acl= "";
763 foreach ($entry['acl'] as $name => $object){
764 if (count($object)){
765 $acl.= "$name, ";
766 }
767 }
768 $summary.= sprintf(_("Contains settings for these objects: %s"), preg_replace('/, $/', '', $acl));
769 }
771 /* Summarize members */
772 if ($summary != ""){
773 $summary.= ", ";
774 }
775 if (count($entry['members'])){
776 $summary.= _("Members:")." ";
777 foreach ($entry['members'] as $cn){
778 $cn= preg_replace('/ \[.*$/', '', $cn);
779 $summary.= $cn.", ";
780 }
781 } else {
782 $summary.= _("ACL is valid for all users");
783 }
785 return (preg_replace('/, $/', '', $summary));
786 }
789 function loadAclEntry($new= FALSE)
790 {
791 /* New entry gets presets... */
792 if ($new){
793 $this->aclType= 'sub';
794 $this->recipients= array();
795 $this->aclContents= array();
796 } else {
797 $acl= $this->gosaAclTemplate[$this->currentIndex];
798 $this->aclType= $acl['type'];
799 $this->recipients= $acl['members'];
800 $this->aclContents= $acl['acl'];
801 }
803 $this->wasNewEntry= $new;
804 }
807 function aclPostHandler()
808 {
809 if (isset($_POST['save_acl'])){
810 $this->save();
811 return TRUE;
812 }
814 return FALSE;
815 }
818 function save()
819 {
820 /* Assemble ACL's */
821 $tmp_acl= array();
822 foreach ($this->gosaAclTemplate as $prio => $entry){
823 $final= "";
824 $members= "";
825 if (isset($entry['members'])){
826 foreach ($entry['members'] as $key => $dummy){
827 $members.= base64_encode(preg_replace('/^.:/', '', $key)).',';
828 }
829 }
830 $final= $prio.":".$entry['type'].":".preg_replace('/,$/', '', $members);
832 /* ACL's if needed */
833 if ($entry['type'] != "reset" && $entry['type'] != "role"){
834 $acl= ":";
835 if (isset($entry['acl'])){
836 foreach ($entry['acl'] as $object => $contents){
838 /* Only save, if we've some contents in there... */
839 if (count($contents)){
840 $acl.= $object.";";
842 foreach($contents as $attr => $permission){
844 /* First entry? Its the one for global settings... */
845 if ($attr == '0'){
846 $acl.= $permission;
847 } else {
848 $acl.= '#'.$attr.';'.$permission;
849 }
851 }
852 $acl.= ',';
853 }
855 }
856 }
857 $final.= preg_replace('/,$/', '', $acl);
858 }
860 $tmp_acl[]= $final;
861 }
863 /* Call main method */
864 plugin::save();
866 /* Finally (re-)assign it... */
867 $this->attrs["gosaAclTemplate"]= $tmp_acl;
869 /* Remove acl from this entry if it is empty... */
870 if (!count($tmp_acl)){
871 /* Remove attribute */
872 if ($this->initially_was_account){
873 $this->attrs["gosaAclTempalte"]= array();
874 } else {
875 if (isset($this->attrs["gosaAclTemplate"])){
876 unset($this->attrs["gosaAclTemplate"]);
877 }
878 }
879 }
881 /* Do LDAP modifications */
882 $ldap= $this->config->get_ldap_link();
884 /* Check if object already exists */
885 $ldap->cat($this->dn);
886 if($ldap->count()){
887 $ldap->cd($this->dn);
888 $this->cleanup();
889 $ldap->modify ($this->attrs);
890 }else{
891 $ldap->cd($this->config->current['BASE']);
892 $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$this->dn));
893 $ldap->cd($this->dn);
894 $ldap->add($this->attrs);
895 }
897 show_ldap_error($ldap->get_error(), sprintf(_("Saving ACLs with dn '%s' failed."),$this->dn));
899 /* Refresh users ACLs */
900 $ui= get_userinfo();
901 $ui->loadACL();
902 $_SESSION['ui']= $ui;
903 }
906 function remove_from_parent()
907 {
908 echo "Role should be deleted here- What happens with assigned roles ... ";
909 }
911 function save_object()
912 {
913 plugin::save_object();
914 if(isset($_POST['acl_role_posted'])){
916 /* Get base selection */
917 if(isset($_POST['base'])){
918 $tmp = $this->get_allowed_bases();
919 if(isset($tmp[$_POST['base']])){
920 $this->base = $_POST['base'];
921 }
922 }
923 }
924 }
926 /* Return plugin informations for acl handling */
927 function plInfo()
928 {
929 return (array(
930 "plShortName" => _("Role"),
931 "plDescription" => _("ACL roles"),
932 "plSelfModify" => FALSE,
933 "plDepends" => array(),
934 "plPriority" => 0,
935 "plSection" => array("admin"),
936 "plCategory" => array("aclroles" => array("objectClass" => "gosaRole", "description" => _("Acl roles"))),
938 "plProvidedAcls" => array(
939 "cn" => _("Name"),
940 "base" => _("Base"),
941 "description" => _("Description"))
942 ));
943 }
945 }
947 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
948 ?>