1 <?php
3 class aclResolver
4 {
5 private $classMapping = array();
6 private $aclTypes = array();
7 private $affectingACLs = array();
9 private $renderedList = "";
11 // The users 'dn' and 'uid' used to verify the collected acls
12 private $validateDn;
13 private $validateUid;
14 private $acl_category;
15 private $parent;
17 function __construct($config, $dn, $parent)
18 {
19 $this->config = &$config;
20 $this->dn = $dn;
21 $this->parent = $parent;
23 // Replace this with a user defined one later.
24 $ui = get_userinfo();
25 $this->validateUid = $ui->uid;
26 $this->validateDn = $ui->dn;
28 // Build class mapping - only once, will not change during session.
29 if(!session::is_set('aclConverter::classMapping')){
30 $tmp= session::global_get('plist');
31 $plist= $tmp->info;
32 $map = array();
33 $map['all']= _("All categories");
34 foreach($plist as $class => $plInfo){
35 if(isset($plInfo['plCategory']) && is_array($plInfo['plCategory'])){
36 foreach($plInfo['plCategory'] as $category => $desc){
37 if(!is_numeric($category)){
38 $map[$category] = $desc['description'];
39 }
40 }
41 }
42 }
43 foreach($plist as $class => $plInfo){
44 if(isset($plInfo['plCategory']) && is_array($plInfo['plCategory'])){
45 foreach($plInfo['plCategory'] as $category => $desc){
46 if(!is_numeric($category)){
47 $map[$category."/".$class] = $map[$category]." - ".$plInfo['plDescription'];
48 }else{
49 $map[$desc."/".$class] = $map[$desc]." - ".$plInfo['plDescription'];
50 }
51 }
53 }
54 }
55 session::set('aclConverter::classMapping', $map);
56 }
57 $this->classMapping = session::get('aclConverter::classMapping');
59 // Define ACL type translations
60 $this->aclTypes= array("reset" => _("Reset ACLs"),
61 "one" => _("One level"),
62 "base" => _("Current object"),
63 "sub" => _("Complete subtree"),
64 "psub" => _("Complete subtree (permanent)"),
65 "role" => _("Use ACL defined in role"));
67 // Enforce to reload acl result
68 $this->renderedList = "";
69 }
72 function reload()
73 {
74 // Go through all ACLs and get those matching the objects dn.
75 $ui = get_userinfo();
76 $ui->reset_acl_cache();
77 $ui->loadACL();
79 // Get ACL category for the current object.
80 if(isset($this->parent->acl_category) && !empty($this->parent->acl_category)){
81 $this->acl_category = preg_replace("/\/$/","",$this->parent->acl_category);
82 }
84 foreach($ui->allACLs as $dn => $acls){
85 if(preg_match("/".preg_quote($dn,'/')."$/i", $this->dn)){
87 // Foreach dn there is a collection of ACLs indexed by their priority
88 foreach($acls as $prio => $acl){
89 if($acl['type'] == "reset"){
90 $this->affectingACLs[$dn][$prio] = $acl;
91 continue;
92 }else{
94 // Only get those entries with a relevant acl-category
95 foreach($acl['acl'] as $category => $attributes){
96 if(preg_match("/^all($|\/)/", $category) ||
97 preg_match("/^".$this->acl_category."($|\/)/", $category)){
98 $this->affectingACLs[$dn][$prio] = $acl;
99 continue;
100 }
101 }
102 }
103 }
104 }
105 }
106 }
110 /*! \brief Create a human readable HTML result
111 */
112 function getReadableACL()
113 {
114 if(empty($this->renderedList)){
116 $this->reload();
118 // Base template - each entry start with this
119 $tpl =
120 "\n <tr class='acl-viewer-head %s'>".
121 "\n <td>%s</td>".
122 "\n <td colspan=2><b>%s</b> - %s</td>".
123 "\n </tr>".
124 "\n %s".
125 "\n <tr>".
126 "\n <td colspan=3><hr></td>".
127 "\n </tr>";
129 // If the acl consists of a user-object-filter then this template is used.
130 $filter_tpl =
131 "\n <tr class='%s'>".
132 "\n <td></td>".
133 "\n <td><b>"._("Filter")."</b></td>".
134 "\n <td><ul><li>%s</li></ul></td>".
135 "\n </tr>";
137 // Used to display ACL owner of type "group"
138 $gmem_tpl =
139 "\n <tr class='%s'>".
140 "\n <td></td>".
141 "\n <td><b>"._("Group members")."</b></td>".
142 "\n <td><ul>%s</ul></td>".
143 "\n </tr>";
145 // Used to display ACL owner of type "user"
146 $umem_tpl =
147 "\n <tr class='%s'>".
148 "\n <td></td>".
149 "\n <td><b>"._("Members")."</b></td>".
150 "\n <td><ul>%s</ul></td>".
151 "\n </tr>";
153 // Used to display the acl contents, except 'reset' and 'role'
154 $acl_tpl =
155 "\n <tr class='%s'>".
156 "\n <td></td>".
157 "\n <td><b>"._("Acls")."</b></td>".
158 "\n <td><ul>%s</ul></td>".
159 "\n </tr>";
162 $str = "<table summary='"._("Object permissions")."' class='acl-viewer'>";
163 $ldap = $this->config->get_ldap_link();
164 $ldap->cd($this->config->current['BASE']);
165 $ui = get_userinfo();
166 foreach($this->affectingACLs as $dn => $acls){
167 foreach($acls as $acl){
168 $gmem = $umem = $defs = "";
170 // Prepare entry icon (department or element?)
171 $image = (isset($this->config->idepartments[$dn]))? "images/select_department.png":"images/lists/element.png";
173 // The acl type (sub,psub,reset...)
174 $aclType = $this->aclTypes[$acl['type']];
176 // Does the filter match for current object?
177 $filter ="";
178 $match = TRUE;
179 if(!empty($acl['filter'])){
180 $match = $ldap->object_match_filter($this->dn,$acl['filter']);
181 $filter= $acl['filter'];
182 if(!$match){
183 $filter= "<span>".$filter."</span>";
184 }
185 }
187 // Check if we are part of the member list
188 if($match){
189 $found = FALSE;
190 foreach($acl['members'] as $mem => $desc){
191 if($mem == "U:{$this->validateDn}"){
192 $found = TRUE;
193 break;
194 }
195 if($mem == "G:*"){
196 $found = TRUE;
197 break;
198 }
199 if(preg_match("/^G:/", $mem)){
200 $gdn = preg_replace("/^G:/","",$mem);
201 $ldap->cat($gdn,array('memberUid'));
202 if($ldap->count()){
203 $attrs = $ldap->fetch();
204 if(isset($attrs['memberUid']) && in_array($this->validateUid, $attrs['memberUid'])){
205 $found = TRUE;
206 }
207 }
208 break;
209 }
210 }
211 $match = $found;
212 }
214 $class = "";
215 if(!$match){
216 $class = "acl-viewer-blocked";
217 }
219 if(!empty($filter)) $filter =sprintf($filter_tpl,$class,$filter);
221 foreach($acl['members'] as $type => $name){
222 if(preg_match("/^G/", $type))
223 $gmem .= "\n <li>".$name."</li>";
224 }
225 if(!empty($gmem)) $gmem =sprintf($gmem_tpl,$class,$gmem);
227 foreach($acl['members'] as $type => $name){
228 if(!preg_match("/^G/", $type))
229 $umem .= "\n <li>".$name."</li>";
230 }
231 if(!empty($umem)) $umem = sprintf($umem_tpl,$class,$umem);
233 if($acl['type']!='reset'){
234 foreach($acl['acl'] as $type => $acl){
235 if(isset($this->classMapping[$type])){
236 $defs .= "<li>".$this->classMapping[$type].": ".$this->aclToString($acl)."</li>";
237 }else{
238 $defs .= "<li>".$type.": ".$this->aclToString($acl)."</li>";
239 }
240 }
241 if(!empty($defs)) $defs = sprintf($acl_tpl, $class,$defs);
242 }
243 $str.= sprintf($tpl,$class, image($image), $dn, $aclType, $filter.$gmem.$umem.$defs);
244 }
245 }
246 $str .= "</table>";
247 $this->renderedList = $str;
248 }
249 return($this->renderedList);
250 }
252 function aclToString($acls)
253 {
254 $str ="<ul>";
255 foreach($acls as $name => $acl){
256 if($name == "0") $name = _("All");
257 $str .= "<li>".$name;
258 $str .= "<ul>";
259 if(preg_match("/s/", $acl)){
260 $str.="<li>"._("Grant permission to owner").'</li>';
261 }
262 if(preg_match("/r/", $acl)) $str.="<li>"._("read").'</li>';
263 if(preg_match("/w/", $acl)) $str.="<li>"._("write").'</li>';
264 if(preg_match("/c/", $acl)) $str.="<li>"._("Create").'</li>';
265 if(preg_match("/d/", $acl)) $str.="<li>"._("Remove").'</li>';
266 if(preg_match("/m/", $acl)) $str.="<li>"._("Move").'</li>';
267 $str.= "</ul>";
268 }
269 return($str."</ul>");
270 }
271 }
273 ?>