/*
* Copyright (C) 2006-2008 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.jlan.smb.nt;
import org.alfresco.jlan.util.DataPacker;
/**
* Secutiry Descriptor Class
*
* @author gkspencer
*/
public class SecurityDescriptor {
// Get/set security descriptor flags
public final static int Owner = 0x0001;
public final static int Group = 0x0002;
public final static int DACL = 0x0004;
public final static int SACL = 0x0008;
// Security descriptor control flags
public final static int OwnerDefaulted = 0x0001;
public final static int GroupDefaulted = 0x0002;
public final static int DACLPresent = 0x0004;
public final static int DACLDefaulted = 0x0008;
public final static int SACLPresent = 0x0010;
public final static int SACLDefaulted = 0x0020;
public final static int DACLAutoInheritReq = 0x0100;
public final static int SACLAutoInheritReq = 0x0200;
public final static int DACLAutoInherited = 0x0400;
public final static int SACLAutoInherited = 0x0800;
public final static int DACLProtected = 0x1000;
public final static int SACLProtected = 0x2000;
public final static int SelfRelative = 0x8000;
// Object types
public final static int File = 0;
public final static int Directory = 1;
public final static int NamedPipe = 2;
public final static int RegistryKey = 3;
public final static int User = 4;
public final static int Kernel = 5;
// Object name and type
private String m_name;
private int m_type;
// Revision and control flags
private int m_revision = 1;
private int m_control;
// Owner/group SIDs
private SID m_owner;
private SID m_group;
// Discretionary ACL
private ACL m_dacl;
// System ACL
private ACL m_sacl;
/**
* Default constructor
*/
public SecurityDescriptor() {
}
/**
* Class constructor
*
* @param name String
* @param type int
*/
public SecurityDescriptor(String name, int type) {
m_name = name;
m_type = type;
}
/**
* Class constructor
*
* @param name String
* @param type int
* @param owner SID
* @param group SID
* @param dacl ACL
* @param sacl ACL
*/
public SecurityDescriptor(String name, int type, SID owner, SID group, ACL dacl, ACL sacl) {
m_name = name;
m_type = type;
m_owner = owner;
m_group = group;
m_dacl = dacl;
m_sacl = sacl;
}
/**
* Check if the descriptor is self-relative
*
* @return boolean
*/
public final boolean isSelfRelative() {
return hasControlFlag(SelfRelative);
}
/**
* Return the revision
*
* @return int
*/
public final int getRevision() {
return m_revision;
}
/**
* Check if the security descriptor has an owner SID
*
* @return boolean
*/
public final boolean hasOwner() {
return m_owner != null ? true : false;
}
/**
* Return the owner SID
*
* @return SID
*/
public final SID getOwner() {
return m_owner;
}
/**
* Check if the security descriptor has a group SID
*
* @return boolean
*/
public final boolean hasGroup() {
return m_group != null ? true : false;
}
/**
* Return the group SID
*
* @return SID
*/
public final SID getGroup() {
return m_group;
}
/**
* Check if the security descriptor has a discretionary ACL
*
* @return boolean
*/
public final boolean hasDACL() {
return m_dacl != null ? true : false;
}
/**
* Return the discretionary ACL
*
* @return ACL
*/
public final ACL getDACL() {
return m_dacl;
}
/**
* Check if the security descriptor has a system ACL
*
* @return boolean
*/
public final boolean hasSACL() {
return m_sacl != null ? true : false;
}
/**
* Return the system ACL
*
* @return ACL
*/
public final ACL getSACL() {
return m_sacl;
}
/**
* Set the owner SID
*
* @param sid SID
*/
public final void setOwner(SID sid) {
m_owner = sid;
}
/**
* Set the group SID
*
* @param sid SID
*/
public final void setGroup(SID sid) {
m_group = sid;
}
/**
* Set the discretionary ACL
*
* @param acl ACL
*/
public final void setDACL(ACL acl) {
m_dacl = acl;
}
/**
* Set the system ACL
*
* @param acl ACL
*/
public final void setSACL(ACL acl) {
m_sacl = acl;
}
/**
* Set the control flags
*
* @param flg int
*/
public final void setControlFlags(int flg) {
m_control = flg;
}
/**
* Load the security descriptor from the specified buffer
*
* @param buf byte[]
* @param off int
* @return int
* @exception LoadException
*/
public final int loadDescriptor(byte[] buf, int off)
throws LoadException {
// Get the revision and control flags
m_revision = DataPacker.getIntelShort(buf, off);
m_control = DataPacker.getIntelShort(buf, off + 2);
// Make sure the security descriptor is self-raltive, if not then abort the load
if ( isSelfRelative() == false)
throw new LoadException("Security descriptor not self-relative, cannot load");
// Clear any current settings
m_owner = null;
m_group = null;
m_dacl = null;
m_sacl = null;
// Get the offset to the owner SID, and load if available
int pos = DataPacker.getIntelInt(buf, off + 4);
int endPos = off + 20;
if ( pos != 0) {
// Load the owner SID
m_owner = new SID();
endPos = m_owner.loadSID(buf, off + pos, false);
}
// Get the offset to the group SID, and load if available
pos = DataPacker.getIntelInt(buf, off + 8);
if ( pos != 0) {
// Load the group SID
m_group = new SID();
endPos = m_group.loadSID(buf, off + pos, false);
}
// Get the offset to the system ACL, and load if available
pos = DataPacker.getIntelInt(buf, off + 12);
if ( pos != 0) {
// Load the system ACL
m_sacl = new ACL();
endPos = m_sacl.loadACL(buf, off + pos);
}
// Get the offset to the discretionary ACL, and load if available
pos = DataPacker.getIntelInt(buf, off + 16);
if ( pos != 0) {
// Load the discretionary ACL
m_dacl = new ACL();
endPos = m_dacl.loadACL(buf, off + pos);
}
// Return the end position of the security descriptor
return endPos;
}
/**
* Save the security descriptor to the specified buffer
*
* @param buf byte[]
* @param off int
* @return int
* @exception SaveException
*/
public final int saveDescriptor(byte[] buf, int off)
throws SaveException {
// Pack the security descriptor
DataPacker.putIntelShort(m_revision,buf,off);
// Make sure the self-relative flag is set
if ( isSelfRelative() == false)
m_control += SelfRelative;
// Check if the SACL flag is set, if present
if ( hasSACL() && hasControlFlag(SACLPresent) == false)
m_control += SACLPresent;
// Check if the DACL flag is set, if present
if ( hasDACL() && hasControlFlag(DACLPresent) == false)
m_control += DACLPresent;
// Pack the control flags
DataPacker.putIntelShort(m_control,buf, off + 2);
// Clear the section offsets
DataPacker.putZeros(buf, off + 4, 16);
// Pack the owner SID, if available
int pos = off + 20;
if ( hasOwner()) {
// Pack the owner SID
DataPacker.putIntelInt(pos-off, buf, off+4); // offset to owner SID
pos = getOwner().saveSID(buf, pos);
}
// Pack the group SID, if available
if ( hasGroup()) {
// Pack the group SID
DataPacker.putIntelInt(pos-off, buf, off+8); // offset to group SID
pos = getGroup().saveSID(buf, pos);
}
// Pack the system ACL, if available
if ( hasSACL()) {
// Pack the SACL
DataPacker.putIntelInt(pos-off, buf, off + 12); // offset to SACL
pos = getSACL().saveACL(buf,pos);
}
// Pack the discretionary ACL, if available
if ( hasDACL()) {
// Pack the DACL
DataPacker.putIntelInt(pos-off, buf, off + 16); // offset to DACL
pos = getDACL().saveACL(buf,pos);
}
// Return the end offset
return pos;
}
/**
* Check if the specified control flag is set
*
* @param flg int
* @return boolean
*/
protected final boolean hasControlFlag(int flg) {
if (( m_control & flg) != 0)
return true;
return false;
}
/**
* Return the security descriptor as a string
*
* @return String
*/
public String toString() {
StringBuffer str = new StringBuffer();
str.append("[");
if ( hasOwner()) {
str.append("Owner:");
str.append(getOwner().toString());
str.append(",");
}
if ( hasGroup()) {
str.append("Group:");
str.append(getGroup().toString());
str.append(",");
}
if ( hasDACL()) {
str.append("DACL:");
str.append(getDACL().toString());
str.append(",");
}
if ( hasSACL()) {
str.append("SACL:");
str.append(getSACL().toString());
}
str.append("]");
return str.toString();
}
}