All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.kerb4j.server.marshall.pac.PacLogonInfo Maven / Gradle / Ivy

There is a newer version: 0.2.0
Show newest version
package com.kerb4j.server.marshall.pac;

import com.kerb4j.server.marshall.Kerb4JException;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.util.Date;

public class PacLogonInfo {

    private Date logonTime;
    private Date logoffTime;
    private Date kickOffTime;
    private Date pwdLastChangeTime;
    private Date pwdCanChangeTime;
    private Date pwdMustChangeTime;
    private short logonCount;
    private short badPasswordCount;
    private String userName;
    private String userDisplayName;
    private String logonScript;
    private String profilePath;
    private String homeDirectory;
    private String homeDrive;
    private String serverName;
    private String domainName;
    private PacSid userSid;
    private PacSid groupSid;
    private PacSid[] groupSids;
    private PacSid[] resourceGroupSids;
    private PacSid[] extraSids;
    private int userAccountControl;
    private int userFlags;

    public PacLogonInfo(byte[] data) throws Kerb4JException {
        try {
            PacDataInputStream pacStream = new PacDataInputStream(new DataInputStream(
                    new ByteArrayInputStream(data)));

            // Skip firsts
            pacStream.skipBytes(20);

            // Dates
            logonTime = pacStream.readFiletime();
            logoffTime = pacStream.readFiletime();
            kickOffTime = pacStream.readFiletime();
            pwdLastChangeTime = pacStream.readFiletime();
            pwdCanChangeTime = pacStream.readFiletime();
            pwdMustChangeTime = pacStream.readFiletime();

            // User related strings as UnicodeStrings
            PacUnicodeString userNameString = pacStream.readUnicodeString();
            PacUnicodeString userDisplayNameString = pacStream.readUnicodeString();
            PacUnicodeString logonScriptString = pacStream.readUnicodeString();
            PacUnicodeString profilePathString = pacStream.readUnicodeString();
            PacUnicodeString homeDirectoryString = pacStream.readUnicodeString();
            PacUnicodeString homeDriveString = pacStream.readUnicodeString();

            // Some counts
            logonCount = pacStream.readShort();
            badPasswordCount = pacStream.readShort();

            // IDs for user
            PacSid userId = pacStream.readId();
            PacSid groupId = pacStream.readId();

            // Groups information
            int groupCount = pacStream.readInt();
            int groupPointer = pacStream.readInt();

            // User flags about PAC Logon Info content
            userFlags = pacStream.readInt();
            boolean hasExtraSids = (userFlags & PacConstants.LOGON_EXTRA_SIDS) == PacConstants.LOGON_EXTRA_SIDS;
            boolean hasResourceGroups = (userFlags & PacConstants.LOGON_RESOURCE_GROUPS) == PacConstants.LOGON_RESOURCE_GROUPS;

            // Skip some reserved fields (User Session Key)
            pacStream.skipBytes(16);

            // Server related strings as UnicodeStrings
            PacUnicodeString serverNameString = pacStream.readUnicodeString();
            PacUnicodeString domainNameString = pacStream.readUnicodeString();

            // ID for domain (used with relative IDs to get SIDs)
            int domainIdPointer = pacStream.readInt();

            // Skip some reserved fields
            pacStream.skipBytes(8);

            userAccountControl = pacStream.readInt();

            // Skip some reserved fields
            pacStream.skipBytes(28);

            // Extra SIDs information
            int extraSidCount = pacStream.readInt();
            int extraSidPointer = pacStream.readInt();

            // ID for resource groups domain (used with IDs to get SIDs)
            int resourceDomainIdPointer = pacStream.readInt();

            // Resource groups information
            int resourceGroupCount = pacStream.readInt();
            int resourceGroupPointer = pacStream.readInt();

            // User related strings
            userName = userNameString.check(pacStream.readString());
            userDisplayName = userDisplayNameString.check(pacStream.readString());
            logonScript = logonScriptString.check(pacStream.readString());
            profilePath = profilePathString.check(pacStream.readString());
            homeDirectory = homeDirectoryString.check(pacStream.readString());
            homeDrive = homeDriveString.check(pacStream.readString());

            // Groups data
            PacGroup[] groups = new PacGroup[0];
            if (groupPointer != 0) {
                int realGroupCount = pacStream.readInt();
                if (realGroupCount != groupCount) {
                    Object[] args = new Object[]{groupCount, realGroupCount};
                    throw new Kerb4JException("pac.groups.invalid.size", args, null);
                }
                groups = new PacGroup[groupCount];
                for (int i = 0; i < groupCount; i++) {
                    pacStream.align(4);
                    PacSid id = pacStream.readId();
                    int attributes = pacStream.readInt();
                    groups[i] = new PacGroup(id, attributes);
                }
            }

            // Server related strings
            serverName = serverNameString.check(pacStream.readString());
            domainName = domainNameString.check(pacStream.readString());

            // ID for domain (used with relative IDs to get SIDs)
            PacSid domainId = null;
            if (domainIdPointer != 0)
                domainId = pacStream.readSid();

            // Extra SIDs data
            PacSidAttributes[] extraSidAtts = new PacSidAttributes[0];
            if (hasExtraSids && extraSidPointer != 0) {
                int realExtraSidCount = pacStream.readInt();
                if (realExtraSidCount != extraSidCount) {
                    Object[] args = new Object[]{extraSidCount, realExtraSidCount};
                    throw new Kerb4JException("pac.extrasids.invalid.size", args, null);
                }
                extraSidAtts = new PacSidAttributes[extraSidCount];
                int[] pointers = new int[extraSidCount];
                int[] attributes = new int[extraSidCount];
                for (int i = 0; i < extraSidCount; i++) {
                    pointers[i] = pacStream.readInt();
                    attributes[i] = pacStream.readInt();
                }
                for (int i = 0; i < extraSidCount; i++) {
                    PacSid sid = (pointers[i] != 0) ? pacStream.readSid() : null;
                    extraSidAtts[i] = new PacSidAttributes(sid, attributes[i]);
                }
            }

            // ID for resource domain (used with relative IDs to get SIDs)
            PacSid resourceDomainId = null;
            if (resourceDomainIdPointer != 0)
                resourceDomainId = pacStream.readSid();

            // Resource groups data
            PacGroup[] resourceGroups = new PacGroup[0];
            if (resourceSIDCompressionEnabled(resourceDomainId)) {
                // Resource groups data
                if (hasResourceGroups && resourceGroupPointer != 0) {
                    int realResourceGroupCount = pacStream.readInt();
                    if (realResourceGroupCount != resourceGroupCount) {
                        Object[] args = new Object[]{resourceGroupCount, realResourceGroupCount};
                        throw new Kerb4JException("pac.resourcegroups.invalid.size", args, null);
                    }
                    resourceGroups = new PacGroup[resourceGroupCount];
                    for (int i = 0; i < resourceGroupCount; i++) {
                        byte[] relativeId = new byte[4]; // is an unsigned int
                        pacStream.readFully(relativeId);
                        int attributes = (int) pacStream.readInt();
                        PacSid relativeSid = PacSid.createFromSubs(relativeId);
                        PacSid id = PacSid.append(resourceDomainId, relativeSid);
                        resourceGroups[i] = new PacGroup(id, attributes);
                    }
                }
            } else {

                if (hasResourceGroups && resourceGroupPointer != 0) {
                    int realResourceGroupCount = pacStream.readInt();
                    if (realResourceGroupCount != resourceGroupCount) {
                        Object[] args = new Object[]{resourceGroupCount, realResourceGroupCount};
                        throw new Kerb4JException("pac.resourcegroups.invalid.size", args, null);
                    }
                    resourceGroups = new PacGroup[resourceGroupCount];
                    for (int i = 0; i < resourceGroupCount; i++) {
                        PacSid id = pacStream.readSid();
                        int attributes = pacStream.readInt();
                        resourceGroups[i] = new PacGroup(id, attributes);
                    }
                }
            }

            // Extract Extra SIDs
            extraSids = new PacSid[extraSidAtts.length];
            for (int i = 0; i < extraSidAtts.length; i++) {
                extraSids[i] = extraSidAtts[i].getId();
            }

            // Compute Resource Group IDs with Resource Domain ID to get SIDs
            resourceGroupSids = new PacSid[resourceGroups.length];
            for (int i = 0; i < resourceGroups.length; i++) {
                resourceGroupSids[i] = PacSid.append(resourceDomainId, resourceGroups[i].getId());
            }

            // Compute User IDs with Domain ID to get User SIDs
            // First extra is user if userId is empty
            if (!userId.isEmpty() && !userId.isBlank()) {
                userSid = PacSid.append(domainId, userId);
            } else if (extraSids.length > 0) {
                userSid = extraSids[0];
            }
            groupSid = PacSid.append(domainId, groupId);

            // Compute Group IDs with Domain ID to get Group SIDs
            groupSids = new PacSid[groups.length];
            for (int i = 0; i < groups.length; i++) {
                groupSids[i] = PacSid.append(domainId, groups[i].getId());
            }
        } catch (IOException e) {
            throw new Kerb4JException("pac.logoninfo.malformed", null, e);
        }
    }

    public Date getLogonTime() {
        return logonTime;
    }

    public Date getLogoffTime() {
        return logoffTime;
    }

    public Date getKickOffTime() {
        return kickOffTime;
    }

    public Date getPwdLastChangeTime() {
        return pwdLastChangeTime;
    }

    public Date getPwdCanChangeTime() {
        return pwdCanChangeTime;
    }

    public Date getPwdMustChangeTime() {
        return pwdMustChangeTime;
    }

    public short getLogonCount() {
        return logonCount;
    }

    public short getBadPasswordCount() {
        return badPasswordCount;
    }

    public String getUserName() {
        return userName;
    }

    public String getUserDisplayName() {
        return userDisplayName;
    }

    public String getLogonScript() {
        return logonScript;
    }

    public String getProfilePath() {
        return profilePath;
    }

    public String getHomeDirectory() {
        return homeDirectory;
    }

    public String getHomeDrive() {
        return homeDrive;
    }

    public String getServerName() {
        return serverName;
    }

    public String getDomainName() {
        return domainName;
    }

    public PacSid getUserSid() {
        return userSid;
    }

    public PacSid getGroupSid() {
        return groupSid;
    }

    public PacSid[] getGroupSids() {
        return groupSids;
    }

    public PacSid[] getResourceGroupSids() {
        return resourceGroupSids;
    }

    public PacSid[] getExtraSids() {
        return extraSids;
    }

    public int getUserAccountControl() {
        return userAccountControl;
    }

    public int getUserFlags() {
        return userFlags;
    }

    private boolean resourceSIDCompressionEnabled(PacSid resourceDomainId) {
        return resourceDomainId != null;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy