/*
* eXist Open Source Native XML Database
* Copyright (C) 2013 The eXist Project
* http://exist-db.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$
*/
package org.exist.security.internal.aider;
import java.io.IOException;
import org.exist.security.AbstractUnixStylePermission;
import org.exist.security.Group;
import org.exist.security.SecurityManager;
import org.exist.security.Account;
import org.exist.security.Permission;
import org.exist.security.PermissionDeniedException;
import org.exist.security.Subject;
import org.exist.storage.io.VariableByteInput;
import org.exist.storage.io.VariableByteOutputStream;
import org.exist.util.SyntaxException;
/**
* Unix style permission details.
*
* @author Adam Retter <adam@exist-db.org>
* @author <a href="mailto:shabanovd@gmail.com">Dmitriy Shabanov</a>
*/
public class UnixStylePermissionAider extends AbstractUnixStylePermission implements PermissionAider {
//owner, default to DBA
private Account owner;
private Group ownerGroup;
private int mode;
public UnixStylePermissionAider() {
owner = new UserAider(SecurityManager.DBA_USER);
}
/**
* Construct a Permission with given mode
*
* @param mode The mode
*/
public UnixStylePermissionAider(final int mode) {
this();
this.mode = mode;
}
/**
* Construct a permission with given user, group and mode
*
* @param user
* @param group
* @param mode
*/
public UnixStylePermissionAider(final String user, final String group, final int mode) {
this.owner = new UserAider(user);
this.ownerGroup = new GroupAider(group);
this.mode = mode;
}
@Override
public boolean isSetGid() {
return ((mode >>> 9) & SET_GID) == SET_GID;
}
@Override
public boolean isSetUid() {
return ((mode >>> 9) & SET_UID) == SET_UID;
}
@Override
public boolean isSticky() {
return ((mode >>> 9) & STICKY) == STICKY;
}
@Override
public void setSetUid(final boolean setUid) {
if(setUid) {
this.mode = mode | (SET_UID << 9);
} else {
this.mode = mode & (~(SET_UID << 9));
}
}
@Override
public void setSetGid(final boolean setGid) {
if(setGid) {
this.mode = mode | (SET_GID << 9);
} else {
this.mode = mode & (~(SET_GID << 9));
}
}
@Override
public void setSticky(final boolean sticky) {
if(sticky) {
this.mode = mode | (STICKY << 9);
} else {
this.mode = mode & (~(STICKY << 9));
}
}
/**
* Get the active mode for group
*
* @return The group mode value
*/
@Override
public int getGroupMode() {
return (mode & 0x38) >> 3;
}
/**
* Gets the user who owns this resource
*
* @return The owner value
*/
@Override
public Account getOwner() {
return owner;
}
/**
* Gets the group
*
* @return The ownerGroup value
*/
@Override
public Group getGroup() {
return ownerGroup;
}
/**
* Get the mode
*
* @return The mode value
*/
@Override
public int getMode() {
return mode;
}
/**
* Get the active mode for others
*
* @return The other mode value
*/
@Override
public int getOtherMode() {
return mode & 0x7;
}
/**
* Get the active mode for the owner
*
* @return The user mode value
*/
@Override
public int getOwnerMode() {
return (mode & 0x1c0) >> 6;
}
/**
* Set the owner group
*
* @param group The group value
*/
@Override
public void setGroup(final Group group) {
this.ownerGroup = group;
}
/**
* Set the owner group
*
* @param group The group name
*/
@Override
public void setGroup(final String group) {
this.ownerGroup = new GroupAider(group);
}
@Override
public void setGroupFrom(Permission other) throws PermissionDeniedException {
this.ownerGroup = new GroupAider(other.getGroup().getName());
}
/**
* Sets mode for group
*
*@param groupMode The new group mode value
*/
@Override
public void setGroupMode(final int groupMode) {
this.mode |= (groupMode << 3);
}
/**
* Set the owner passed as User object
*
*@param user The new owner value
*/
@Override
public void setOwner(final Account user) {
this.owner = user;
}
/**
* Set the owner
*
*@param user The new owner value
*/
@Override
public void setOwner(final String user) {
this.owner = new UserAider(user);
}
/**
* Set mode
*
*@param mode The new mode value
*/
@Override
public void setMode(final int mode) {
this.mode = mode;
}
/**
* Set mode for others
*
*@param otherMode The new public mode value
*/
@Override
public void setOtherMode(final int otherMode) {
this.mode |= otherMode ;
}
/**
* Set mode for the owner
*
*@param ownerMode The new owner mode value
*/
@Override
public void setOwnerMode(final int ownerMode) {
this.mode |= (ownerMode << 6);
}
/**
* Format mode
*
*@return Description of the Return Value
*/
@Override
public String toString() {
final char ch[] = new char[] {
(mode & (READ << 6)) == 0 ? UNSET_CHAR : READ_CHAR,
(mode & (WRITE << 6)) == 0 ? UNSET_CHAR : WRITE_CHAR,
(mode & (SET_UID << 9)) == 0 ? ((mode & (EXECUTE << 6)) == 0 ? UNSET_CHAR : EXECUTE_CHAR) : ((mode & (EXECUTE << 6)) == 0 ? SETUID_CHAR_NO_EXEC : SETUID_CHAR),
(mode & (READ << 3)) == 0 ? UNSET_CHAR : READ_CHAR,
(mode & (WRITE << 3)) == 0 ? UNSET_CHAR : WRITE_CHAR,
(mode & (SET_GID << 9)) == 0 ? ((mode & (EXECUTE << 3)) == 0 ? UNSET_CHAR : EXECUTE_CHAR) : ((mode & (EXECUTE << 3)) == 0 ? SETGID_CHAR_NO_EXEC : SETGID_CHAR),
(mode & READ) == 0 ? UNSET_CHAR : READ_CHAR,
(mode & WRITE) == 0 ? UNSET_CHAR : WRITE_CHAR,
(mode & (STICKY << 9)) == 0 ? ((mode & EXECUTE) == 0 ? UNSET_CHAR : EXECUTE_CHAR) : ((mode & EXECUTE) == 0 ? STICKY_CHAR_NO_EXEC : STICKY_CHAR)
};
return String.valueOf(ch);
}
public static UnixStylePermissionAider fromString(final String modeStr) throws SyntaxException {
if(modeStr == null || !(modeStr.length() == 9 || modeStr.length() == 12)){
throw new SyntaxException("Invalid Permission String '" + modeStr + "'");
}
int mode = 0;
for(int i = 0; i < modeStr.length(); i=i+3) {
for(final char c : modeStr.substring(i, i + 3).toCharArray()) {
switch(c) {
case READ_CHAR:
mode |= (READ << (6 - i));
break;
case WRITE_CHAR:
mode |= (WRITE << (6 - i));
break;
case EXECUTE_CHAR:
mode |= (EXECUTE << (6 - i));
break;
case SETUID_CHAR | SETGID_CHAR:
if(i == 0) {
mode |= (SET_UID << 9);
} else if(i == 3) {
mode |= (SET_GID << 9);
}
mode |= (EXECUTE << (6 - i));
break;
case SETUID_CHAR_NO_EXEC | SETGID_CHAR_NO_EXEC:
if(i == 0) {
mode |= (SET_UID << 9);
} else if(i == 3) {
mode |= (SET_GID << 9);
}
break;
case STICKY_CHAR:
mode |= (STICKY << 9);
mode |= (EXECUTE << (6 - i));
break;
case STICKY_CHAR_NO_EXEC:
mode |= (STICKY << 9);
break;
case UNSET_CHAR:
break;
default:
throw new SyntaxException("Unknown char '" + c + "' in mode string '" + modeStr + "'");
}
}
}
return new UnixStylePermissionAider(mode);
}
@Override
public boolean validate(final Subject user, final int mode) {
throw new UnsupportedOperationException("Validation of Permission Aider is unsupported");
}
@Override
public void setGroup(final int id) {
ownerGroup = new GroupAider(id);
}
@Override
public void setOwner(final int id) {
owner = new UserAider(id);
}
@Override
public void write(final VariableByteOutputStream ostream) {
throw new UnsupportedOperationException("Serialization of permission Aider is unsupported");
}
@Override
public void read(final VariableByteInput istream) throws IOException {
throw new UnsupportedOperationException("De-Serialization of permission Aider is unsupported");
}
@Override
public boolean isCurrentSubjectDBA() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public boolean isCurrentSubjectOwner() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public boolean isCurrentSubjectInGroup() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public boolean isCurrentSubjectInGroup(final int groupId) {
throw new UnsupportedOperationException("Not supported yet.");
}
}