1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package com.gridsystems.innergrid.kernel.ixos.usersystem;
19
20 import java.io.File;
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.Iterator;
24 import java.util.List;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28
29 import com.gridsystems.utils.FileProperties;
30
31 import com.gridsystems.innergrid.kernel.KernelException;
32 import com.gridsystems.innergrid.kernel.genericutils.ApiUtils;
33 import com.gridsystems.innergrid.kernel.server.KernelContext;
34
35 import com.gridsystems.innergrid.kernel.ixos.Configuration;
36 import com.gridsystems.innergrid.kernel.ixos.filesystem.FilePermissions;
37 import com.gridsystems.innergrid.kernel.ixos.filesystem.IxosSecurityManager;
38 import com.gridsystems.innergrid.kernel.ixos.filesystem.PermissionsManager;
39 import com.gridsystems.innergrid.kernel.ixos.filesystem.RepositoryFileFilter;
40
41
42
43
44
45
46
47
48
49
50
51
52
53 public final class PermissionsCleanerThread extends Thread {
54
55
56
57 private static Log log = LogFactory.getLog(PermissionsCleanerThread.class);
58
59
60
61
62 private static PermissionsCleanerThread instance = null;
63
64
65
66
67 private boolean launched = false;
68
69
70
71
72 private long sleep = 0L;
73
74
75
76
77 private ApiUserSystemImpl userSystem = ApiUserSystemImpl.getInstance();
78
79
80
81
82 private PermissionsManager permissionsManager = PermissionsManager.getInstance();
83
84
85
86
87 private RepositoryFileFilter filter = new RepositoryFileFilter(false, true, true);
88
89
90
91
92
93 private File rootFile = Configuration.getRepositoryRoot();
94
95
96
97
98
99
100
101 private PermissionsCleanerThread(long sleep) {
102 this.sleep = sleep;
103 this.setPriority(Thread.MIN_PRIORITY);
104 }
105
106
107
108
109
110
111
112
113
114 public void setRootFile(File rootFile) {
115 if (rootFile != null && rootFile.exists()
116 && IxosSecurityManager.inRepository(rootFile)) {
117 this.rootFile = rootFile;
118 }
119 }
120
121
122
123
124
125
126 public File getRootFile() {
127 return this.rootFile;
128 }
129
130
131
132
133
134
135 public boolean isLaunched() {
136 return launched;
137 }
138
139
140
141
142
143
144 public void run() {
145 try {
146 Thread.sleep(this.sleep);
147
148 if (log.isInfoEnabled()) {
149 log.info("Thread begins running");
150 }
151
152
153
154 this.launched = true;
155
156
157
158
159 KernelContext.getContext().setEffectiveUser(Configuration.getPrivilegedUser());
160
161 if (isUserSystemLoaded()) {
162 this.cleanFilePermissions();
163 this.cleanAllAclPermissions();
164 } else {
165
166
167
168 log.error("The UserSystem data was not correctly loaded");
169 log.error("File and ACL permissions will not be cleaned");
170 }
171 } catch (InterruptedException ie) {
172
173 } catch (KernelException ke) {
174 log.warn("Could not switch to superuser mode.");
175 }
176 }
177
178
179
180
181 private void cleanFilePermissions() {
182
183 try {
184
185 File fileToClean = null;
186 if (this.rootFile.isDirectory()) {
187 fileToClean = this.rootFile;
188 } else {
189 if (this.rootFile.getName().startsWith(IxosSecurityManager.SECURITY_PREFIX)) {
190
191 fileToClean = this.rootFile;
192 } else {
193
194 fileToClean = IxosSecurityManager.findOwnSecurityFile(this.rootFile);
195 if (!fileToClean.exists()) {
196
197
198
199 return;
200 }
201 }
202 }
203 if (log.isInfoEnabled()) {
204 log.info("Cleaning lost permisions of " + fileToClean);
205 }
206 cleanFilePermissions(fileToClean, true);
207 if (log.isInfoEnabled()) {
208 log.info("Permisions of " + this.rootFile + " successfully cleaned");
209 }
210 } catch (KernelException ke) {
211 log.error("Controled exception happened while cleaning permissions of "
212 + this.rootFile, ke);
213 }
214 }
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231 private void cleanFilePermissions(File f, boolean firstRecursion)
232 throws KernelException {
233
234 if (f.isDirectory()) {
235 if (log.isDebugEnabled()) {
236 log.debug("Going to clean files in " + f);
237 }
238 if (firstRecursion) {
239 File directorySecurityFile = IxosSecurityManager.findOwnSecurityFile(f);
240 if (directorySecurityFile.exists()) {
241 cleanFilePermissions(directorySecurityFile, false);
242 }
243 }
244 File[] files = f.listFiles(this.filter);
245 if (files != null) {
246 for (int i = 0; i < files.length; i++) {
247 cleanFilePermissions(files[i], false);
248 }
249 }
250 } else {
251 cleanFilePermissions(f);
252 }
253 }
254
255
256
257
258
259
260
261
262
263 private void cleanFilePermissions(File f) throws KernelException {
264
265 this.permissionsManager.lock(f);
266
267 boolean locked = true;
268 try {
269 FilePermissions[][] permissions;
270 synchronized (FileProperties.synchronize) {
271 FileProperties props = new FileProperties(f);
272 permissions = this.permissionsManager.getPermissionsLists(props);
273 }
274 List<FilePermissions> newPermList = new ArrayList<FilePermissions>();
275 boolean changed = false;
276
277 for (FilePermissions filePerms : permissions[0]) {
278 if (this.userSystem.userExists(filePerms.getName())) {
279 newPermList.add(filePerms);
280 } else {
281 changed = true;
282 }
283 }
284
285 for (FilePermissions filePerms : permissions[1]) {
286 if (this.userSystem.roleExists(filePerms.getName())) {
287 newPermList.add(filePerms);
288 } else {
289 changed = true;
290 }
291 }
292 if (changed) {
293
294 log.debug("Changing mod file " + f.getName());
295 FilePermissions[] newPermArray = new FilePermissions[newPermList.size()];
296 newPermList.toArray(newPermArray);
297 this.permissionsManager.quickChmod(f, newPermArray);
298
299 locked = false;
300 }
301 } catch (Exception e) {
302 log.error("Exception catched when cleaning lost permissions of file system: ", e);
303 throw ApiUtils.processException(e);
304 } finally {
305 if (locked) {
306 this.permissionsManager.unlock(f);
307 }
308 }
309 }
310
311
312
313
314 private void cleanAllAclPermissions() {
315 try {
316 if (log.isInfoEnabled()) {
317 log.info("Starting cleaning of ACLs");
318 }
319
320 AclList aclList = AclList.getInstance();
321 String[] domains = aclList.getAllAclDomains();
322
323 for (int i = 0; i < domains.length; i++) {
324
325
326 Collection acls = aclList.getAllAcls(domains[i]);
327 Iterator it = acls.iterator();
328 while (it.hasNext()) {
329 Acl acl = (Acl) it.next();
330 if (log.isDebugEnabled()) {
331 log.debug("Going to clean Acl : " + acl.getName());
332 }
333 if (this.cleanAclPermission(acl)) {
334 if (log.isDebugEnabled()) {
335 log.debug("Saving modified Acl: " + acl.getName());
336 }
337 acl.store();
338 }
339 }
340 }
341 if (log.isInfoEnabled()) {
342 log.info("Cleaning of ACLs successfully finished");
343 }
344 } catch (KernelException e) {
345 log.error("Exception retrieved when cleaning ACLs", e);
346 }
347 }
348
349
350
351
352
353
354
355
356
357
358
359 private boolean cleanAclPermission(Acl acl) throws KernelException {
360 boolean modified = false;
361
362
363 String[] permissions = acl.getPermissions();
364 for (int i = 0; i < permissions.length; i++) {
365
366
367 String[] roles = acl.getRoles(permissions[i]);
368 for (int j = 0; j < roles.length; j++) {
369 if (!this.userSystem.roleExists(roles[j])) {
370 modified = true;
371 acl.revokeRole(permissions[i], roles[j]);
372 }
373 }
374
375
376 String[] users = acl.getDirectUsers(permissions[i]);
377 for (int j = 0; j < users.length; j++) {
378 if (!this.userSystem.userExists(users[j])) {
379 modified = true;
380 acl.revokeUser(permissions[i], users[j]);
381 }
382 }
383 }
384
385
386 String[] roleOwners = acl.getRoleOwners();
387 for (int i = 0; i < roleOwners.length; i++) {
388 if (!this.userSystem.roleExists(roleOwners[i])) {
389 modified = true;
390 acl.removeRoleOwner(roleOwners[i]);
391 }
392 }
393
394
395 String[] userOwners = acl.getUserOwners();
396 for (int i = 0; i < userOwners.length; i++) {
397 if (!this.userSystem.userExists(userOwners[i])) {
398 modified = true;
399 acl.removeUserOwner(userOwners[i]);
400 }
401 }
402
403
404 return modified;
405 }
406
407
408
409
410
411
412
413
414
415
416
417
418
419 public static void startCleaner(long delay) {
420
421
422 if (instance != null && instance.isAlive()) {
423 if (instance.isLaunched()) {
424
425 instance.interrupt();
426 } else {
427
428 return;
429 }
430 }
431 instance = new PermissionsCleanerThread(delay);
432 instance.start();
433 }
434
435
436
437
438
439 public static void stopCleaner() {
440 if (instance != null && instance.isAlive()) {
441 instance.interrupt();
442 }
443 }
444
445
446
447
448
449
450
451
452 private boolean isUserSystemLoaded() throws KernelException {
453 ApiUserSystemImpl apiUserSystem = ApiUserSystemImpl.getInstance();
454 String[] roleNames = apiUserSystem.getAllRoleNames();
455 String[] userNames = apiUserSystem.getAllUserNames();
456 return ((userNames != null) && (userNames.length > 0) && (roleNames != null)
457 && (roleNames.length > 0));
458 }
459 }