jcifs.smb.SID Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jcifs-ng Show documentation
Show all versions of jcifs-ng Show documentation
A pure-java CIFS/SMB client library
/* jcifs smb client library in Java
* Copyright (C) 2006 "Michael B. Allen"
* "Eric Glass"
*
* This library 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.1 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcifs.smb;
import java.io.IOException;
import java.util.StringTokenizer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jcifs.CIFSContext;
import jcifs.RuntimeCIFSException;
import jcifs.dcerpc.rpc;
import jcifs.internal.util.SMBUtil;
import jcifs.util.Hexdump;
/**
* Internal representation of SIDs
*
* A Windows SID is a numeric identifier used to represent Windows
* accounts. SIDs are commonly represented using a textual format such as
* S-1-5-21-1496946806-2192648263-3843101252-1029 but they may
* also be resolved to yield the name of the associated Windows account
* such as Administrators or MYDOM\alice.
*
* Consider the following output of examples/SidLookup.java:
*
*
* toString: S-1-5-21-4133388617-793952518-2001621813-512
* toDisplayString: WNET\Domain Admins
* getType: 2
* getTypeText: Domain group
* getDomainName: WNET
* getAccountName: Domain Admins
*
*
* @internal
*/
public class SID extends rpc.sid_t implements jcifs.SID {
private static final Logger log = LoggerFactory.getLogger(SID.class);
static final String[] SID_TYPE_NAMES = {
"0", "User", "Domain group", "Domain", "Local group", "Builtin group", "Deleted", "Invalid", "Unknown"
};
/**
*
*/
public static final int SID_FLAG_RESOLVE_SIDS = 0x0001;
/**
* Well known SID: EVERYONE
*/
public static SID EVERYONE = null;
/**
* Well known SID: CREATOR_OWNER
*/
public static SID CREATOR_OWNER = null;
/**
* Well known SID: SYSTEM
*/
public static SID SYSTEM = null;
static {
try {
EVERYONE = new SID("S-1-1-0");
CREATOR_OWNER = new SID("S-1-3-0");
SYSTEM = new SID("S-1-5-18");
}
catch ( SmbException se ) {
log.error("Failed to create builtin SIDs", se);
}
}
/**
* Convert a sid_t to byte array
*
* @param sid
* @return byte encoded form
*/
public static byte[] toByteArray ( rpc.sid_t sid ) {
byte[] dst = new byte[1 + 1 + 6 + sid.sub_authority_count * 4];
int di = 0;
dst[ di++ ] = sid.revision;
dst[ di++ ] = sid.sub_authority_count;
System.arraycopy(sid.identifier_authority, 0, dst, di, 6);
di += 6;
for ( int ii = 0; ii < sid.sub_authority_count; ii++ ) {
jcifs.util.Encdec.enc_uint32le(sid.sub_authority[ ii ], dst, di);
di += 4;
}
return dst;
}
int type;
String domainName = null;
String acctName = null;
String origin_server = null;
CIFSContext origin_ctx = null;
/**
* Construct a SID from it's binary representation.
*
*
* @param src
* @param si
*/
public SID ( byte[] src, int si ) {
this.revision = src[ si++ ];
this.sub_authority_count = src[ si++ ];
this.identifier_authority = new byte[6];
System.arraycopy(src, si, this.identifier_authority, 0, 6);
si += 6;
if ( this.sub_authority_count > 100 )
throw new RuntimeCIFSException("Invalid SID sub_authority_count");
this.sub_authority = new int[this.sub_authority_count];
for ( int i = 0; i < this.sub_authority_count; i++ ) {
this.sub_authority[ i ] = SMBUtil.readInt4(src, si);
si += 4;
}
}
/**
* Construct a SID from it's textual representation such as
* S-1-5-21-1496946806-2192648263-3843101252-1029.
*
* @param textual
* @throws SmbException
*/
public SID ( String textual ) throws SmbException {
StringTokenizer st = new StringTokenizer(textual, "-");
if ( st.countTokens() < 3 || !st.nextToken().equals("S") )
// need S-N-M
throw new SmbException("Bad textual SID format: " + textual);
this.revision = Byte.parseByte(st.nextToken());
String tmp = st.nextToken();
long id = 0;
if ( tmp.startsWith("0x") )
id = Long.parseLong(tmp.substring(2), 16);
else
id = Long.parseLong(tmp);
this.identifier_authority = new byte[6];
for ( int i = 5; id > 0; i-- ) {
this.identifier_authority[ i ] = (byte) ( id % 256 );
id >>= 8;
}
this.sub_authority_count = (byte) st.countTokens();
if ( this.sub_authority_count > 0 ) {
this.sub_authority = new int[this.sub_authority_count];
for ( int i = 0; i < this.sub_authority_count; i++ )
this.sub_authority[ i ] = (int) ( Long.parseLong(st.nextToken()) & 0xFFFFFFFFL );
}
}
/**
* Construct a SID from a domain SID and an RID
* (relative identifier). For example, a domain SID
* S-1-5-21-1496946806-2192648263-3843101252 and RID 1029 would
* yield the SID S-1-5-21-1496946806-2192648263-3843101252-1029.
*
* @param domsid
* @param rid
*/
public SID ( SID domsid, int rid ) {
this.revision = domsid.revision;
this.identifier_authority = domsid.identifier_authority;
this.sub_authority_count = (byte) ( domsid.sub_authority_count + 1 );
this.sub_authority = new int[this.sub_authority_count];
int i;
for ( i = 0; i < domsid.sub_authority_count; i++ ) {
this.sub_authority[ i ] = domsid.sub_authority[ i ];
}
this.sub_authority[ i ] = rid;
}
/**
* Construct a relative SID
*
* @param domsid
* @param id
*/
public SID ( SID domsid, SID id ) {
this.revision = domsid.revision;
this.identifier_authority = domsid.identifier_authority;
this.sub_authority_count = (byte) ( domsid.sub_authority_count + id.sub_authority_count );
this.sub_authority = new int[this.sub_authority_count];
int i;
for ( i = 0; i < domsid.sub_authority_count; i++ ) {
this.sub_authority[ i ] = domsid.sub_authority[ i ];
}
for ( i = domsid.sub_authority_count; i < domsid.sub_authority_count + id.sub_authority_count; i++ ) {
this.sub_authority[ i ] = id.sub_authority[ i - domsid.sub_authority_count ];
}
}
/**
*
* @param sid
* @param type
* @param domainName
* @param acctName
* @param decrementAuthority
*/
public SID ( rpc.sid_t sid, int type, String domainName, String acctName, boolean decrementAuthority ) {
this.revision = sid.revision;
this.sub_authority_count = sid.sub_authority_count;
this.identifier_authority = sid.identifier_authority;
this.sub_authority = sid.sub_authority;
this.type = type;
this.domainName = domainName;
this.acctName = acctName;
if ( decrementAuthority ) {
this.sub_authority_count--;
this.sub_authority = new int[this.sub_authority_count];
for ( int i = 0; i < this.sub_authority_count; i++ ) {
this.sub_authority[ i ] = sid.sub_authority[ i ];
}
}
}
/**
*
* {@inheritDoc}
*
* @see jcifs.SID#unwrap(java.lang.Class)
*/
@SuppressWarnings ( "unchecked" )
@Override
public T unwrap ( Class t ) {
if ( t.isAssignableFrom(this.getClass()) ) {
return (T) this;
}
throw new ClassCastException();
}
/**
*
* @return encoded SID
*/
public byte[] toByteArray () {
return toByteArray(this);
}
/**
*
* @return whether the SID is empty (no sub-authorities)
*/
public boolean isEmpty () {
return this.sub_authority_count == 0;
}
/**
*
* @return whether the SID is blank (all sub-authorities zero)
*/
public boolean isBlank () {
boolean blank = true;
for ( int sub : this.sub_authority )
blank = blank && ( sub == 0 );
return blank;
}
/**
*
* @return domain SID
*/
@Override
public SID getDomainSid () {
return new SID(this, SID_TYPE_DOMAIN, this.domainName, null, getType() != SID_TYPE_DOMAIN);
}
/**
* Get the RID
*
* This is the last subauthority identifier
*
* @return the RID
*/
@Override
public int getRid () {
if ( getType() == SID_TYPE_DOMAIN )
throw new IllegalArgumentException("This SID is a domain sid");
return this.sub_authority[ this.sub_authority_count - 1 ];
}
@Override
public int getType () {
if ( this.origin_server != null )
resolveWeak();
return this.type;
}
@Override
public String getTypeText () {
if ( this.origin_server != null )
resolveWeak();
return SID_TYPE_NAMES[ this.type ];
}
@Override
public String getDomainName () {
if ( this.origin_server != null )
resolveWeak();
if ( this.type == SID_TYPE_UNKNOWN ) {
String full = toString();
return full.substring(0, full.length() - getAccountName().length() - 1);
}
return this.domainName;
}
@Override
public String getAccountName () {
if ( this.origin_server != null )
resolveWeak();
if ( this.type == SID_TYPE_UNKNOWN )
return "" + this.sub_authority[ this.sub_authority_count - 1 ];
if ( this.type == SID_TYPE_DOMAIN )
return "";
return this.acctName;
}
@Override
public int hashCode () {
int hcode = this.identifier_authority[ 5 ];
for ( int i = 0; i < this.sub_authority_count; i++ ) {
hcode += 65599 * this.sub_authority[ i ];
}
return hcode;
}
@Override
public boolean equals ( Object obj ) {
if ( obj instanceof SID ) {
SID sid = (SID) obj;
if ( sid == this )
return true;
if ( sid.sub_authority_count == this.sub_authority_count ) {
int i = this.sub_authority_count;
while ( i-- > 0 ) {
if ( sid.sub_authority[ i ] != this.sub_authority[ i ] ) {
return false;
}
}
for ( i = 0; i < 6; i++ ) {
if ( sid.identifier_authority[ i ] != this.identifier_authority[ i ] ) {
return false;
}
}
return sid.revision == this.revision;
}
}
return false;
}
/**
* Return the numeric representation of this sid such as
* S-1-5-21-1496946806-2192648263-3843101252-1029.
*/
@Override
public String toString () {
String ret = "S-" + ( this.revision & 0xFF ) + "-";
if ( this.identifier_authority[ 0 ] != (byte) 0 || this.identifier_authority[ 1 ] != (byte) 0 ) {
ret += "0x";
ret += Hexdump.toHexString(this.identifier_authority, 0, 6);
}
else {
long shift = 0;
long id = 0;
for ( int i = 5; i > 1; i-- ) {
id += ( this.identifier_authority[ i ] & 0xFFL ) << shift;
shift += 8;
}
ret += id;
}
for ( int i = 0; i < this.sub_authority_count; i++ )
ret += "-" + ( this.sub_authority[ i ] & 0xFFFFFFFFL );
return ret;
}
@Override
public String toDisplayString () {
if ( this.origin_server != null )
resolveWeak();
if ( this.domainName != null ) {
String str;
if ( this.type == SID_TYPE_DOMAIN ) {
str = this.domainName;
}
else if ( this.type == SID_TYPE_WKN_GRP || this.domainName.equals("BUILTIN") ) {
if ( this.type == SID_TYPE_UNKNOWN ) {
str = toString();
}
else {
str = this.acctName;
}
}
else {
str = this.domainName + "\\" + this.acctName;
}
return str;
}
return toString();
}
/**
* Manually resolve this SID. Normally SIDs are automatically
* resolved. However, if a SID is constructed explicitly using a SID
* constructor, JCIFS will have no knowledge of the server that created the
* SID and therefore cannot possibly resolve it automatically. In this case,
* this method will be necessary.
*
* @param authorityServerName
* The FQDN of the server that is an authority for the SID.
* @param tc
* Context to use
* @throws IOException
*/
public void resolve ( String authorityServerName, CIFSContext tc ) throws IOException {
SID[] sids = new SID[1];
sids[ 0 ] = this;
tc.getSIDResolver().resolveSids(tc, authorityServerName, sids);
}
void resolveWeak () {
if ( this.origin_server != null ) {
try {
resolve(this.origin_server, this.origin_ctx);
}
catch ( IOException ioe ) {
log.debug("Failed to resolve SID", ioe);
}
finally {
this.origin_server = null;
this.origin_ctx = null;
}
}
}
/**
* Get members of the group represented by this SID, if it is one.
*
* @param authorityServerName
* @param tc
* @param flags
* @return the members of the group
* @throws IOException
*/
public jcifs.SID[] getGroupMemberSids ( String authorityServerName, CIFSContext tc, int flags ) throws IOException {
if ( this.type != SID_TYPE_DOM_GRP && this.type != SID_TYPE_ALIAS )
return new SID[0];
return tc.getSIDResolver().getGroupMemberSids(tc, authorityServerName, getDomainSid(), getRid(), flags);
}
/**
* @param context
* @param server
*/
public void initContext ( String server, CIFSContext context ) {
this.origin_ctx = context;
this.origin_server = server;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy