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