/*
* 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;
/**
* Security Id Class
*
* @author gkspencer
*/
public class SID {
// Constants
//
// Predefined identifier authorites
public static final int IdentAuthNull = 0;
public static final int IdentAuthWorld = 1;
public static final int IdentAuthLocal = 2;
public static final int IdentAuthCreator = 3;
public static final int IdentAuthNonUnique = 4;
public static final int IdentAuthNT = 5;
// Predefined sub-authority RIDs
public static final int SubAuthNull = 0;
public static final int SubAuthWorld = 0;
public static final int SubAuthLocal = 0;
public static final int SubAuthCreatorOwner = 0;
public static final int SubAuthCreatorGroup = 1;
public static final int SubAuthNTDialup = 1;
public static final int SubAuthNTNetwork = 2;
public static final int SubAuthNTBatch = 3;
public static final int SubAuthNTInteractive = 4;
public static final int SubAuthNTService = 6;
public static final int SubAuthNTAnonymous = 7;
public static final int SubAuthNTProxy = 8;
public static final int SubAuthNTEnterpriseCtrl = 9;
public static final int SubAuthNTPrincipalSelf = 10;
public static final int SubAuthNTAuthenticated = 11;
public static final int SubAuthNTRestrictedCode = 12;
public static final int SubAuthNTTerminalServer = 13;
public static final int SubAuthNTLocalSystem = 18;
public static final int SubAuthNTNonUnique = 21;
public static final int SubAuthNTBuiltinDomain = 32;
// Minimum binary size for a SID
private static final int MinimumBinarySize = 12;
// Revision
private int m_revision;
// Identifier authority
private byte[] m_identAuth;
// Subauthority count and values
private int m_subAuthCnt;
private int[] m_subAuth;
// Relative id
private int m_rid = -1;
// Object name
private String m_name;
/**
* Default constructor
*/
public SID() {
}
/**
* Class constructor
*
* @param name String
* @param rev int
* @param auth int
* @param subauth int
*/
public SID(String name, int rev, int auth, int subauth) {
m_name = name;
m_revision = rev;
m_identAuth = new byte[6];
m_identAuth[5] = (byte) ( auth & 0xFF);
m_subAuthCnt = 1;
m_subAuth = new int[1];
m_subAuth[0] = subauth;
m_rid = -1;
}
/**
* Class constructor
*
* @param rev int
* @param auth int
* @param subauth int
* @param rid int
*/
public SID(int rev, int auth, int subauth, int rid) {
m_revision = rev;
m_identAuth = new byte[6];
m_identAuth[5] = (byte) ( auth & 0xFF);
m_subAuthCnt = 1;
m_subAuth = new int[1];
m_subAuth[0] = subauth;
m_rid = rid;
}
/**
* Class constructor
*
* @param rev int
* @param auth int
* @param subauth1 int
* @param subauth2 int
* @param rid int
*/
public SID(int rev, int auth, int subauth1, int subauth2, int rid) {
m_revision = rev;
m_identAuth = new byte[6];
m_identAuth[5] = (byte) ( auth & 0xFF);
m_subAuthCnt = 2;
m_subAuth = new int[2];
m_subAuth[0] = subauth1;
m_subAuth[1] = subauth2;
m_rid = rid;
}
/**
* Copy constructor
*
* @param sid SID
*/
public SID(SID sid) {
m_revision = sid.getRevision();
m_identAuth = sid.getIdentifierAuthority();
m_subAuthCnt = sid.getSubauthorityCount();
if ( sid.hasRID())
m_subAuthCnt--;
m_subAuth = new int[m_subAuthCnt];
for ( int i = 0; i < m_subAuth.length; i++)
m_subAuth[i] = sid.getSubauthority(i);
m_rid = sid.getRID();
}
/**
* Get the revision
*
* @return int
*/
public final int getRevision() {
return m_revision;
}
/**
* Get the identifier authority
*
* @return byte[]
*/
public final byte[] getIdentifierAuthority() {
return m_identAuth;
}
/**
* Get the sub-authority count
*
* @return int
*/
public final int getSubauthorityCount() {
if ( m_rid != -1)
return m_subAuthCnt + 1;
return m_subAuthCnt;
}
/**
* Get the specified sub-authority
*
* @param idx int
* @return int
*/
public final int getSubauthority(int idx) {
// Range check the index
if ( idx < 0 || idx >= m_subAuthCnt)
return -1;
// Return the sub-authority value
return m_subAuth[idx];
}
/**
* Check if the relative id has been set
*
* @return boolean
*/
public final boolean hasRID() {
return m_rid != -1 ? true : false;
}
/**
* Get the relative id
*
* @return int
*/
public final int getRID() {
return m_rid;
}
/**
* Check if the obect name has been set
*
* @return boolean
*/
public final boolean hasName() {
return m_name != null ? true : false;
}
/**
* Return the object name
*
* @return String
*/
public final String getName() {
return m_name;
}
/**
* Check if the SID matches this SID
*
* @param sid SID
* @return boolean
*/
public final boolean equalsSID(SID sid) {
// Compare the SIDs
if ( getRevision() == sid.getRevision() &&
getIdentifierAuthority() != null &&
sid.getIdentifierAuthority() != null) {
// Compare the identifer authority bytes
byte[] sidIdent = sid.getIdentifierAuthority();
if ( sidIdent.length != m_identAuth.length)
return false;
for ( int i = 0; i < m_identAuth.length; i++) {
if ( m_identAuth[i] != sidIdent[i])
return false;
}
// Compare the sub-authorities
for ( int i = 0; i < getSubauthorityCount(); i++) {
if ( getSubauthority(i) != sid.getSubauthority(i))
return false;
}
// SIDs match
return true;
}
// SIDs do not match
return false;
}
/**
* Set the relative id value
*
* @param id int
*/
public final void setRID(int id) {
m_rid = id;
}
/**
* Set the object name
*
* @param name String
*/
public final void setName(String name) {
m_name = name;
}
/**
* Load the SID from the specified buffer
*
* @param buf byte[]
* @param off int
* @param domain boolean
* @return int
* @exception LoadException
*/
public final int loadSID(byte[] buf, int off, boolean domain)
throws LoadException {
// Check if the buffer is long enough to contain a valid SID
if ((buf.length - off) < MinimumBinarySize)
throw new LoadException("Buffer too short for SID");
// Unpack the SID
m_revision = (int) (buf[off++] & 0xFF);
m_subAuthCnt = (int) (buf[off++] & 0xFF);
if ( m_identAuth == null)
m_identAuth = new byte[6];
for ( int i = 0; i < 6; i++)
m_identAuth[i] = buf[off++];
// Unpack the subauthorities
// Unpack the subauthorities
boolean hasRID = false;
if (domain == false && m_subAuthCnt > 1) {
m_subAuthCnt--;
hasRID = true;
}
m_subAuth = new int[m_subAuthCnt];
for ( int i = 0; i < m_subAuthCnt; i++) {
m_subAuth[i] = DataPacker.getIntelInt(buf, off);
off += 4;
}
if (hasRID) {
m_rid = DataPacker.getIntelInt(buf, off);
off += 4;
}
// Return the end of SID offset
return off;
}
/**
* Save the SID to the specified buffer
*
* @param buf byte[]
* @param off int
* @return int
* @exception SaveException
*/
public final int saveSID(byte[] buf, int off)
throws SaveException {
// Pack the SID
buf[off++] = (byte) ( m_revision & 0xFF);
buf[off++] = (byte) ( m_rid != -1 ? m_subAuthCnt + 1 : m_subAuthCnt);
for ( int i = 0; i < 6; i++)
buf[off++] = m_identAuth[i];
if ( m_subAuth != null) {
for ( int i = 0; i < m_subAuth.length; i++) {
DataPacker.putIntelInt(m_subAuth[i], buf, off);
off += 4;
}
}
if ( m_rid != -1) {
DataPacker.putIntelInt(m_rid, buf, off);
off += 4;
}
return off;
}
/**
* Return the SID as a string, in the standard 'S-r-a-s-s-s-r' format
*
* @return String
*/
public String toString() {
// Check if the name has been set
if ( hasName())
return getName();
// Build the SID string
StringBuffer str = new StringBuffer();
str.append("S-");
str.append(getRevision());
str.append("-");
str.append((int) m_identAuth[5]);
for ( int i = 0; i < m_subAuth.length; i++) {
str.append("-");
str.append(getSubauthority(i));
}
if ( getRID() != -1) {
str.append("-");
str.append(getRID());
}
return str.toString();
}
}