/* * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.dcache.chimera.posix; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class UnixPermissionHandler implements AclHandler { private static final Logger _log = LoggerFactory.getLogger(UnixPermissionHandler.class); private static final UnixPermissionHandler HANDLER = new UnixPermissionHandler(); private UnixPermissionHandler() { } public static UnixPermissionHandler getInstance() { return HANDLER; } private static boolean inGroup(User user, int group) { int userGid = ((UnixUser) user).getGID(); int[] userGids = ((UnixUser) user).getGIDS(); boolean inGroup = false; if (group == userGid) { inGroup = true; } else { for (int gid : userGids) { if (group == gid) { inGroup = true; break; } } } return inGroup; } @Override public boolean isAllowed(Acl acl, User user, int requsetedAcl) { boolean isAllowed = false; int userUid = ((UnixUser) user).getUID(); if (!(acl instanceof UnixAcl)) { return false; } int resourceUid = ((UnixAcl) acl).getOwner(); int resourceGid = ((UnixAcl) acl).getGroup(); int resourcePermissions = ((UnixAcl) acl).getPermission(); if (_log.isDebugEnabled()) { StringBuilder sb = new StringBuilder("ACL request : "); sb.append("user=").append(((UnixUser) user).getUID()).append(':').append(((UnixUser) user).getGID()); sb.append(' '); sb.append("file=").append(resourceUid).append(':').append(resourceGid); sb.append(' '); sb.append("action="); switch (requsetedAcl) { case ACL_READ: sb.append("ACL_READ"); break; case ACL_WRITE: sb.append("ACL_WRITE"); break; case ACL_DELETE: sb.append("ACL_DELETE"); break; case ACL_LOOKUP: sb.append("ACL_LOOKUP"); break; case ACL_ADMINISTER: sb.append("ACL_ADMINISTER"); break; case ACL_INSERT: sb.append("ACL_INSERT"); break; case ACL_LOCK: sb.append("ACL_LOCK"); break; case ACL_EXECUTE: sb.append("ACL_EXECUTE"); break; default: sb.append("ACL_UNKNOWN"); } // switch( requsetedAcl ) _log.debug(sb.toString()); } switch (userUid) { case 0: // root has an access to everything isAllowed = true; break; case -12: // bad (?) user isAllowed = false; break; default: // regular users switch (requsetedAcl) { case ACL_READ: if (resourceUid == userUid) { isAllowed = ((resourcePermissions & 0400) == 0400); } else if (inGroup(user, resourceGid)) { // check for group isAllowed = ((resourcePermissions & 0040) == 0040); } else { // check for others isAllowed = ((resourcePermissions & 0004) == 0004); } break; case ACL_WRITE: if (resourceUid == userUid) { isAllowed = ((resourcePermissions & 0200) == 0200); } else if (inGroup(user, resourceGid)) { // check for group isAllowed = ((resourcePermissions & 0020) == 0020); } else { // check for others isAllowed = ((resourcePermissions & 0002) == 0002); } break; case ACL_DELETE: isAllowed = isAllowed(acl, user, ACL_WRITE); // if there is a sticky bit, only owner allowed to remove if ((resourcePermissions & 01000) == 01000) { System.out.println("Sticky bit set!"); isAllowed = isAllowed && isAllowed(acl, user, ACL_ADMINISTER); } break; case ACL_LOOKUP: isAllowed = isAllowed(acl, user, ACL_READ) && isAllowed(acl, user, ACL_EXECUTE); break; case ACL_ADMINISTER: isAllowed = (resourceUid == userUid); break; case ACL_INSERT: // isAllowed = isAllowed(acl, user, ACL_WRITE) && isAllowed(acl, user, ACL_EXECUTE); isAllowed = isAllowed(acl, user, ACL_WRITE); break; case ACL_LOCK: isAllowed = true; break; case ACL_EXECUTE: if (resourceUid == userUid) { isAllowed = ((resourcePermissions & 0100) == 0100); } else if (inGroup(user, resourceGid)) { // check for group isAllowed = ((resourcePermissions & 0010) == 0010); } else { // check for others isAllowed = ((resourcePermissions & 0001) == 0001); } break; } // switch( requsetedAcl ) } // switch( userUid ) _log.debug("IsAllowed: " + isAllowed); return isAllowed; } }