From: cajus Date: Fri, 9 Feb 2007 06:30:07 +0000 (+0000) Subject: Updates .... X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=737d18edfe81212c42a6975f9690fce09c3d919d;p=gosa.git Updates .... git-svn-id: https://oss.gonicus.de/repositories/gosa/trunk@5711 594d385d-05f5-0310-b6e9-bd551577e9d8 --- diff --git a/TODO b/TODO index 64d85409b..cef784a5e 100644 --- a/TODO +++ b/TODO @@ -4,19 +4,19 @@ Target for 2.6: * Move from gosa.conf-trunk to gosa.conf when we're ready * ACL - - Acl roles should be selectable in acl dialog. + - Acl roles should be selectable in acl dialog - Role checks are missing - - Copy & Paste tmplates for acl roles. + - Copy & Paste tmplates for acl roles - Check Title strings - Check role and acl remove - - Check Base select dialog within roles. + - Check Base select dialog within roles - Implement a kind of "umask" - - Ensure that acls will be the same after renaming and moving objects. + - Ensure that acls will be the same after renaming and moving objects -* Create a Bugtracker - * Redo the setup +* Create a bug submitter + * Make plugin loader react on predefined info values from plugins itself instead of gosa.conf @@ -39,7 +39,9 @@ Target for 2.6: * Evaluate patches for certificate generation -* Bug submitter + +Target for 3.0: +=============== * Complete PHP5 compliance and optimization @@ -47,6 +49,8 @@ Target for 2.6: * Replace PHP IMAP module by self made module +* Make IMAP namespace configurable + * Add possibility to add referrals in department dialog * Fine tuning in Kerberos support @@ -70,5 +74,4 @@ Target for 2.6: * Automatic passwords? Generate a password for a newly created user and display it. -* Make IMAP namespace configurable diff --git a/ihtml/themes/default/acl.tpl b/ihtml/themes/default/acl.tpl index 5df679383..3afb976ea 100644 --- a/ihtml/themes/default/acl.tpl +++ b/ihtml/themes/default/acl.tpl @@ -64,6 +64,12 @@ {$aclSelector} {/if} +{if $aclType eq 'role'} +

 

+

{t}Available roles{/t}

+{$roleSelector} +{/if} +

 

diff --git a/include/class_acl.inc b/include/class_acl.inc index 2d9e72501..41082b310 100644 --- a/include/class_acl.inc +++ b/include/class_acl.inc @@ -154,8 +154,8 @@ class acl extends plugin "one" => _("One level"), "base" => _("Current object"), "sub" => _("Complete subtree"), - "psub" => _("Complete subtree (permanent)")); - //"role" => _("Use ACL defined in role")); + "psub" => _("Complete subtree (permanent)"), + "role" => _("Use ACL defined in role")); } else { $this->aclTypes= array("base" => _("Current object"), "role" => _("Use ACL defined in role")); @@ -451,6 +451,11 @@ class acl extends plugin if ($this->aclType == 'base'){ $smarty->assign('aclSelector', $this->buildAclSelector($this->myAclObjects)); } + + /* Role selector if scope is base */ + if ($this->aclType == 'role'){ + $smarty->assign('roleSelector', "Role selector");#, $this->buildRoleSelector($this->myAclObjects)); + } } if ($this->dialogState == 'edit'){ @@ -466,7 +471,13 @@ class acl extends plugin if ($this->aclObject == 'all'){ $aclObjects['all']= _("All objects in current subtree"); } - $smarty->assign('aclSelector', $this->buildAclSelector($aclObjects)); + + /* Role selector if scope is base */ + if ($this->aclType == 'role'){ + $smarty->assign('roleSelector', "Role selector");#, $this->buildRoleSelector($this->myAclObjects)); + } else { + $smarty->assign('aclSelector', $this->buildAclSelector($aclObjects)); + } } /* Show main page */ @@ -712,7 +723,7 @@ class acl extends plugin break; case 'role': - echo "Role"; + echo "Role: $acl"; break; case 'reset': diff --git a/include/class_ldap.inc b/include/class_ldap.inc index a93aa96c0..c8397fd4a 100644 --- a/include/class_ldap.inc +++ b/include/class_ldap.inc @@ -1233,6 +1233,25 @@ class LDAP{ } } } + + function get_naming_contexts($server, $admin= "", $password= "") + { + /* Build LDAP connection */ + $ds= ldap_connect ($server); + if (!$ds) { + die ("Can't bind to LDAP. No check possible!"); + } + ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3); + $r= ldap_bind ($ds, $admin, $password); + + /* Get base to look for naming contexts */ + $sr = @ldap_read ($ds, "", "objectClass=*", array("namingContexts")); + $attr= @ldap_get_entries($ds,$sr); + + return ($attr[0]['namingcontexts']); + } + + } // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler: diff --git a/plugins/admin/acl/class_aclRole.inc b/plugins/admin/acl/class_aclRole.inc new file mode 100644 index 000000000..0b318d062 --- /dev/null +++ b/plugins/admin/acl/class_aclRole.inc @@ -0,0 +1,947 @@ +dn == "new"){ + $this->base = $_SESSION['CurrentMainBase']; + }else{ + $this->base = preg_replace("/^[^,]+,[^,]+,/","",$this->dn); + } + + /* Load ACL's */ + $this->gosaAclTemplate= array(); + if (isset($this->attrs["gosaAclTemplate"])){ + for ($i= 0; $i<$this->attrs["gosaAclTemplate"]['count']; $i++){ + $acl= $this->attrs["gosaAclTemplate"][$i]; + $this->gosaAclTemplate= array_merge($this->gosaAclTemplate, $this->explodeACL($acl)); + } + } + ksort($this->gosaAclTemplate); + + /* Extract available categories from plugin info list */ + $tmp= get_global('plist'); + $plist= $tmp->info; + $oc = array(); + foreach ($plist as $class => $acls){ + + /* Only feed categories */ + if (isset($acls['plCategory'])){ + + /* Walk through supplied list and feed only translated categories */ + foreach($acls['plCategory'] as $idx => $data){ + + /* Non numeric index means -> base object containing more informations */ + if (preg_match('/^[0-9]+$/', $idx)){ + if (!isset($this->ocMapping[$data])){ + $this->ocMapping[$data]= array(); + $this->ocMapping[$data][]= '0'; + } + $this->ocMapping[$data][]= $class; + } else { + if (!isset($this->ocMapping[$idx])){ + $this->ocMapping[$idx]= array(); + $this->ocMapping[$idx][]= '0'; + } + $this->ocMapping[$idx][]= $class; + $this->aclObjects[$idx]= $data['description']; + + /* Additionally filter the classes we're interested in in "self edit" mode */ + if (is_array($data['objectClass'])){ + foreach($data['objectClass'] as $objectClass){ + if (in_array_ics($objectClass, $oc)){ + $this->myAclObjects[$idx.'/'.$class]= $acls['plDescription']; + break; + } + } + } else { + if (in_array_ics($data['objectClass'], $oc)){ + $this->myAclObjects[$idx.'/'.$class]= $acls['plDescription']; + } + } + } + + } + } + } + $this->aclObjects['all']= '* '._("All categories"); + $this->ocMapping['all']= array('0' => 'all'); + + /* Sort categories */ + asort($this->aclObjects); + + /* Fill acl types */ + $this->aclTypes= array( "reset" => _("Reset ACLs"), + "one" => _("One level"), + "base" => _("Current object"), + "sub" => _("Complete subtree"), + "psub" => _("Complete subtree (permanent)")); + asort($this->aclTypes); + + /* Finally - we want to get saved... */ + $this->is_account= TRUE; + } + + + function execute() + { + /* Call parent execute */ + plugin::execute(); + + /* Base select dialog */ + $once = true; + foreach($_POST as $name => $value){ + if((preg_match("/^chooseBase/",$name) && $once) && ($this->acl_is_moveable())){ + $once = false; + $this->dialog = new baseSelectDialog($this->config,$this,$this->get_allowed_bases()); + $this->dialog->setCurrentBase($this->base); + } + } + + /* Dialog handling */ + if(is_object($this->dialog)){ + /* Must be called before save_object */ + $this->dialog->save_object(); + + if($this->dialog->isClosed()){ + $this->dialog = false; + }elseif($this->dialog->isSelected()){ + + /* Check if selected base is valid */ + $tmp = $this->get_allowed_bases(); + if(isset($tmp[$this->dialog->isSelected()])){ + $this->base = $this->dialog->isSelected(); + } + $this->dialog= false; + }else{ + return($this->dialog->execute()); + } + } + + $tmp= get_global('plist'); + $plist= $tmp->info; + + /* Handle posts */ + if (isset($_POST['new_acl'])){ + $this->dialogState= 'create'; + $this->dialog= TRUE; + $this->currentIndex= count($this->gosaAclTemplate); + $this->loadAclEntry(TRUE); + } + + $new_acl= array(); + $aclDialog= FALSE; + $firstedit= FALSE; + foreach($_POST as $name => $post){ + + /* Actions... */ + if (preg_match('/^acl_edit_.*_x/', $name)){ + $this->dialogState= 'create'; + $firstedit= TRUE; + $this->dialog= TRUE; + $this->currentIndex= preg_replace('/^acl_edit_([0-9]+).*$/', '\1', $name); + $this->loadAclEntry(); + continue; + } + if (preg_match('/^acl_del_.*_x/', $name)){ + unset($this->gosaAclTemplate[preg_replace('/^acl_del_([0-9]+).*$/', '\1', $name)]); + continue; + } + + if (preg_match('/^cat_edit_.*_x/', $name)){ + $this->aclObject= preg_replace('/^cat_edit_([^_]+)_.*$/', '\1', $name); + $this->dialogState= 'edit'; + foreach ($this->ocMapping[$this->aclObject] as $oc){ + if (isset($this->aclContents[$oc])){ + $this->savedAclContents[$oc]= $this->aclContents[$oc]; + } + } + continue; + } + if (preg_match('/^cat_del_.*_x/', $name)){ + $idx= preg_replace('/^cat_del_([^_]+)_.*$/', '\1', $name); + foreach ($this->ocMapping[$idx] as $key){ + unset($this->aclContents["$idx/$key"]); + } + continue; + } + + /* Sorting... */ + if (preg_match('/^sortup_.*_x/', $name)){ + $index= preg_replace('/^sortup_([0-9]+).*$/', '\1', $name); + if ($index > 0){ + $tmp= $this->gosaAclTemplate[$index]; + $this->gosaAclTemplate[$index]= $this->gosaAclTemplate[$index-1]; + $this->gosaAclTemplate[$index-1]= $tmp; + } + continue; + } + if (preg_match('/^sortdown_.*_x/', $name)){ + $index= preg_replace('/^sortdown_([0-9]+).*$/', '\1', $name); + if ($index < count($this->gosaAclTemplate)-1){ + $tmp= $this->gosaAclTemplate[$index]; + $this->gosaAclTemplate[$index]= $this->gosaAclTemplate[$index+1]; + $this->gosaAclTemplate[$index+1]= $tmp; + } + continue; + } + + /* ACL saving... */ + if (preg_match('/^acl_.*_[^xy]$/', $name)){ + $aclDialog= TRUE; + list($dummy, $object, $attribute, $value)= split('_', $name); + + /* Skip for detection entry */ + if ($object == 'dummy') { + continue; + } + + /* Ordinary ACLs */ + if (!isset($new_acl[$object])){ + $new_acl[$object]= array(); + } + if (isset($new_acl[$object][$attribute])){ + $new_acl[$object][$attribute].= $value; + } else { + $new_acl[$object][$attribute]= $value; + } + } + } + + /* Only be interested in new acl's, if we're in the right _POST place */ + if ($aclDialog && $this->aclObject != "" && is_array($this->ocMapping[$this->aclObject])){ + + foreach ($this->ocMapping[$this->aclObject] as $oc){ + unset($this->aclContents[$oc]); + unset($this->aclContents[$this->aclObject.'/'.$oc]); + if (isset($new_acl[$oc])){ + $this->aclContents[$oc]= $new_acl[$oc]; + } + if (isset($new_acl[$this->aclObject.'/'.$oc])){ + $this->aclContents[$this->aclObject.'/'.$oc]= $new_acl[$this->aclObject.'/'.$oc]; + } + } + } + + /* Save new acl in case of base edit mode */ + if ($this->aclType == 'base' && !$firstedit){ + $this->aclContents= $new_acl; + } + + /* Cancel new acl? */ + if (isset($_POST['cancel_new_acl'])){ + $this->dialogState= 'head'; + $this->dialog= FALSE; + if ($this->wasNewEntry){ + unset ($this->gosaAclTemplate[$this->currentIndex]); + } + } + + /* Store ACL in main object? */ + if (isset($_POST['submit_new_acl'])){ + $this->gosaAclTemplate[$this->currentIndex]['type']= $this->aclType; + $this->gosaAclTemplate[$this->currentIndex]['members']= $this->recipients; + $this->gosaAclTemplate[$this->currentIndex]['acl']= $this->aclContents; + $this->dialogState= 'head'; + $this->dialog= FALSE; + } + + /* Cancel edit acl? */ + if (isset($_POST['cancel_edit_acl'])){ + $this->dialogState= 'create'; + foreach ($this->ocMapping[$this->aclObject] as $oc){ + if (isset($this->savedAclContents[$oc])){ + $this->aclContents[$oc]= $this->savedAclContents[$oc]; + } + } + } + + /* Save edit acl? */ + if (isset($_POST['submit_edit_acl'])){ + $this->dialogState= 'create'; + } + + /* Add acl? */ + if (isset($_POST['add_acl']) && $_POST['aclObject'] != ""){ + $this->dialogState= 'edit'; + $this->savedAclContents= array(); + foreach ($this->ocMapping[$this->aclObject] as $oc){ + if (isset($this->aclContents[$oc])){ + $this->savedAclContents[$oc]= $this->aclContents[$oc]; + } + } + } + + /* Save common values */ + foreach (array("aclType", "aclObject", "target") as $key){ + if (isset($_POST[$key])){ + $this->$key= validate($_POST[$key]); + } + } + + /* Create templating instance */ + $smarty= get_smarty(); + + $smarty->assign("bases", $this->get_allowed_bases()); + $smarty->assign("base_select", $this->base); + + $tmp = $this->plInfo(); + foreach($tmp['plProvidedAcls'] as $name => $translation){ + $smarty->assign($name."ACL",$this->getacl($name)); + } + + if ($this->dialogState == 'head'){ + /* Draw list */ + $aclList= new DivSelectBox("aclList"); + $aclList->SetHeight(350); + + /* Fill in entries */ + foreach ($this->gosaAclTemplate as $key => $entry){ + $field1= array("string" => $this->aclTypes[$entry['type']], "attach" => "style='width:100px'"); + $field2= array("string" => $this->assembleAclSummary($entry)); + $action= ""; + $action.= ""; + $action.= ""; + $action.= ""; + + $field3= array("string" => $action, "attach" => "style='border-right:0px;width:50px;text-align:right;'"); + $aclList->AddEntry(array($field1, $field2, $field3)); + } + + $smarty->assign("aclList", $aclList->DrawList()); + } + + if ($this->dialogState == 'create'){ + /* Draw list */ + $aclList= new DivSelectBox("aclList"); + $aclList->SetHeight(450); + + /* Add settings for all categories to the (permanent) list */ + foreach ($this->aclObjects as $section => $dsc){ + $summary= ""; + foreach($this->ocMapping[$section] as $oc){ + if (isset($this->aclContents[$oc]) && count($this->aclContents[$oc]) && isset($this->aclContents[$oc][0]) && + $this->aclContents[$oc][0] != ""){ + + $summary.= "$oc, "; + continue; + } + if (isset($this->aclContents["$section/$oc"]) && count($this->aclContents["$section/$oc"]) && isset($this->aclContents["$section/$oc"][0]) && + $this->aclContents["$section/$oc"][0] != ""){ + + $summary.= "$oc, "; + continue; + } + if (isset($this->aclContents[$oc]) && !isset($this->aclContents[$oc][0]) && count($this->aclContents[$oc])){ + $summary.= "$oc, "; + } + } + + /* Set summary... */ + if ($summary == ""){ + $summary= ''._("No ACL settings for this category").''; + } else { + $summary= sprintf(_("Contains ACLs for these objects: %s"), preg_replace('/, $/', '', $summary)); + } + + $field1= array("string" => $dsc, "attach" => "style='width:140px'"); + $field2= array("string" => $summary); + $action= ""; + $action.= ""; + $field3= array("string" => $action, "attach" => "style='border-right:0px;width:50px'"); + $aclList->AddEntry(array($field1, $field2, $field3)); + } + + $smarty->assign("aclList", $aclList->DrawList()); + $smarty->assign("aclType", $this->aclType); + $smarty->assign("aclTypes", $this->aclTypes); + $smarty->assign("target", $this->target); + + if ($this->aclType == 'base'){ + $smarty->assign('aclSelector', $this->buildAclSelector($this->myAclObjects)); + } + } + + if ($this->dialogState == 'edit'){ + $smarty->assign('headline', sprintf(_("Edit ACL for '%s', scope is '%s'"), $this->aclObjects[$this->aclObject], $this->aclTypes[$this->aclType])); + + /* Collect objects for selected category */ + foreach ($this->ocMapping[$this->aclObject] as $idx => $class){ + if ($idx == 0){ + continue; + } + $aclObjects[$this->aclObject.'/'.$class]= $plist[$class]['plDescription']; + } + if ($this->aclObject == 'all'){ + $aclObjects['all']= _("All objects in current subtree"); + } + $smarty->assign('aclSelector', $this->buildAclSelector($aclObjects)); + } + + /* Show main page */ + $smarty->assign("dialogState", $this->dialogState); + + /* Assign cn and decription if this is a role */ + foreach(array("cn","description") as $name){ + $smarty->assign($name,$this->$name); + } + return ($smarty->fetch (get_template_path('acl_role.tpl',dirname(__FILE__)))); + } + + function sort_by_priority($list) + { + $tmp= get_global('plist'); + $plist= $tmp->info; + asort($plist); + $newSort = array(); + + foreach($list as $name => $translation){ + $na = preg_replace("/^.*\//","",$name); + $prio= $plist[$na]['plPriority'] ; + + $newSort[$name] = $prio; + } + + asort($newSort); + + $ret = array(); + foreach($newSort as $name => $prio){ + $ret[$name] = $list[$name]; + } + return($ret); + } + + function buildAclSelector($list) + { + $display= ""; + $cols= 3; + $tmp= get_global('plist'); + $plist= $tmp->info; + asort($plist); + + /* Add select all/none buttons */ + $style = "style='width:100px;'"; + + $display .= ""; + $display .= ""; + $display .= " - "; + $display .= ""; + $display .= " - "; + + $display .= ""; + $display .= ""; + + $display .= "
"; + + $style = "style='width:50px;'"; + $display .= ""; + $display .= ""; + $display .= ""; + $display .= ""; + $display .= ""; + $display .= " - "; + $display .= ""; + $display .= ""; + $display .= ""; + $display .= " - "; + + $display .= ""; + $display .= ""; + $display .= ""; + $display .= ""; + + /* Build general objects */ + $list =$this->sort_by_priority($list); + foreach ($list as $key => $name){ + + /* Create sub acl if it does not exist */ + if (!isset($this->aclContents[$key])){ + $this->aclContents[$key]= array(); + $this->aclContents[$key][0]= ''; + } + $currentAcl= $this->aclContents[$key]; + + /* Object header */ + if($_SESSION['js']) { + if(isset($_SERVER['HTTP_USER_AGENT']) && preg_match("/gecko/i",$_SERVER['HTTP_USER_AGENT'])) { + $display.= "\n". + "\n ". + "\n ". + "\n ". + "\n "; + } else if (isset($_SERVER['HTTP_USER_AGENT']) && preg_match("/ie/i",$_SERVER['HTTP_USER_AGENT'])) { + $display.= "\n
"._("Object").": $name". + "\n
". + "\n ". + "\n ". + "\n ". + "\n "; + } else { + $display.= "\n
"._("Object").": $name". + "\n
". + "\n ". + "\n ". + "\n "; + } + } else { + $display.= "\n
"._("Object").": $name
". + "\n ". + "\n ". + "\n "; + } + + /* Generate options */ + $spc= "  "; + if ($this->isContainer && $this->aclType != 'base'){ + $options= $this->mkchkbx($key."_0_c", _("Create objects"), preg_match('/c/', $currentAcl[0])).$spc; + $options.= $this->mkchkbx($key."_0_m", _("Move objects"), preg_match('/m/', $currentAcl[0])).$spc; + $options.= $this->mkchkbx($key."_0_d", _("Remove objects"), preg_match('/d/', $currentAcl[0])).$spc; + if ($plist[preg_replace('%^.*/%', '', $key)]['plSelfModify']){ + $options.= $this->mkchkbx($key."_0_s", _("Modifyable by owner"), preg_match('/s/', $currentAcl[0])).$spc; + } + } else { + $options= $this->mkchkbx($key."_0_m", _("Move object"), preg_match('/m/', $currentAcl[0])).$spc; + $options.= $this->mkchkbx($key."_0_d", _("Remove object"), preg_match('/d/', $currentAcl[0])).$spc; + if ($plist[preg_replace('%^.*/%', '', $key)]['plSelfModify']){ + $options.= $this->mkchkbx($key."_0_s", _("Modifyable by owner"), preg_match('/s/', $currentAcl[0])).$spc; + } + } + + /* Global options */ + $more_options= $this->mkchkbx($key."_0_r", _("read"), preg_match('/r/', $currentAcl[0])).$spc; + $more_options.= $this->mkchkbx($key."_0_w", _("write"), preg_match('/w/', $currentAcl[0])); + + $display.= "\n ". + "\n ". + "\n ". + "\n "; + + /* Walk through the list of attributes */ + $cnt= 1; + $splist= $plist[preg_replace('%^.*/%', '', $key)]['plProvidedAcls']; + asort($splist); + if($_SESSION['js']) { + if(isset($_SERVER['HTTP_USER_AGENT']) && preg_match("/gecko/i",$_SERVER['HTTP_USER_AGENT'])) { + $display.= "\n ". + "\n
"._("Object").": $name
$options "._("Complete object").": $more_options
". + "\n