Samples‎ > ‎JNIWrapper Samples‎ > ‎

Modifying the ACLs of an Object using JNIWrapper and WinPack

import com.jniwrapper.*;
import com.jniwrapper.win32.security.Sid;

/**
 * This sample demonstrates how to add ace to object security descriptor.
 * <p/>
 * It is based on <a href="http://msdn.microsoft.com/en-us/library/aa379283%28v=VS.85%29.aspx" >Modifying the ACLs of an Object in C++</a>  article
 */
public class ACLSample {

    public static enum SE_OBJECT_TYPE {
        UNKNOWN_OBJECT_TYPE,
        SE_FILE_OBJECT,
        SE_SERVICE,
        SE_PRINTER,
        SE_REGISTRY_KEY,
        SE_LMSHARE,
        SE_KERNEL_OBJECT,
        SE_WINDOW_OBJECT,
        SE_DS_OBJECT,
        SE_DS_OBJECT_ALL,
        SE_PROVIDER_DEFINED_OBJECT,
        SE_WMIGUID_OBJECT,
        SE_REGISTRY_WOW64_32KEY
    }

    public static enum TRUSTEE_FORM {
        TRUSTEE_IS_SID,
        TRUSTEE_IS_NAME,
        TRUSTEE_BAD_FORM,
        TRUSTEE_IS_OBJECTS_AND_SID,
        TRUSTEE_IS_OBJECTS_AND_NAME
    }

    public static enum ACCESS_MODE {
        NOT_USED_ACCESS,
        GRANT_ACCESS,
        SET_ACCESS,
        DENY_ACCESS,
        REVOKE_ACCESS,
        SET_AUDIT_SUCCESS,
        SET_AUDIT_FAILURE
    }

    public static class ACL extends Structure {
        UInt8 AclRevision = new UInt8();
        UInt8 Sbz1 = new UInt8();
        UInt32 AclSize = new UInt32();
        UInt32 AceCount = new UInt32();
        UInt32 Sbz2 = new UInt32();

        public ACL() {
            init(new Parameter[]{
                    AclRevision,
                    Sbz1,
                    AclSize,
                    AceCount,
                    Sbz2
            }, (short) 8);
        }
    }


    public enum MULTIPLE_TRUSTEE_OPERATION {
        NO_MULTIPLE_TRUSTEE,
        TRUSTEE_IS_IMPERSONATE
    }

    public enum TRUSTEE_TYPE {
        TRUSTEE_IS_UNKNOWN,
        TRUSTEE_IS_USER,
        TRUSTEE_IS_GROUP,
        TRUSTEE_IS_DOMAIN,
        TRUSTEE_IS_ALIAS,
        TRUSTEE_IS_WELL_KNOWN_GROUP,
        TRUSTEE_IS_DELETED,
        TRUSTEE_IS_INVALID,
        TRUSTEE_IS_COMPUTER
    }

    public static class TRUSTEE extends Structure {
        Pointer pMultipleTrustee = new Pointer(TRUSTEE.class);
        Int /*MULTIPLE_TRUSTEE_OPERATION*/ MultipleTrusteeOperation = new Int();
        Int /*TRUSTEE_FORM*/ TrusteeForm = new Int();
        Int /*TRUSTEE_TYPE*/ TrusteeType = new Int();
        Pointer ptstrName = new Pointer(Str.class);

        public TRUSTEE() {
            init(new Parameter[]{
                    pMultipleTrustee,
                    MultipleTrusteeOperation,
                    TrusteeForm,
                    TrusteeType,
                    ptstrName
            }, (short) 8);
        }
    }

    public static class EXPLICIT_ACCESS extends Structure {
        UInt32 grfAccessPermissions = new UInt32();
        Int /*ACCESS_MODE*/ grfAccessMode = new Int();
        UInt32 grfInheritance = new UInt32();
        TRUSTEE Trustee = new TRUSTEE();

        public EXPLICIT_ACCESS() {
            init(new Parameter[]{
                    grfAccessPermissions,
                    grfAccessMode,
                    grfInheritance,
                    Trustee
            }, (short) 8);
        }
    }

    public static class SECURITY_DESCRIPTOR_CONTROL extends UInt32 {
        public SECURITY_DESCRIPTOR_CONTROL() {
        }

        public SECURITY_DESCRIPTOR_CONTROL(long value) {
            super(value);
        }
    }

    public static class SECURITY_DESCRIPTOR extends Structure {
        UInt8 Revision = new UInt8();
        UInt8 Sbz1 = new UInt8();
        SECURITY_DESCRIPTOR_CONTROL Control = new SECURITY_DESCRIPTOR_CONTROL();
        Pointer Owner = new Pointer(Sid.class);
        Pointer Group = new Pointer(Sid.class);
        Pointer Sacl = new Pointer(Sid.class);
        Pointer Dacl = new Pointer(Sid.class);

        public SECURITY_DESCRIPTOR() {
            init(new Parameter[]{
                    Revision,
                    Sbz1,
                    Control,
                    Owner,
                    Group,
                    Sacl,
                    Dacl,
            }, (short) 8);
        }
    }

    static final Library advApi32 = new Library("Advapi32.dll");

    static final long DACL_SECURITY_INFORMATION = 0x00000004L;

    static final long ERROR_SUCCESS = 0;

    /**
     * @param objectName   name of object
     * @param objectType   type of object
     * @param trustee      trustee for new ACE
     * @param trusteeForm  format of trustee structure
     * @param accessRights access mask for new ACE
     * @param accessMode   type of ACE
     * @param inheritance  inheritance flags for new ACE
     */
    public static void addAceToObjectsSecurityDescriptor(
            String objectName,
            SE_OBJECT_TYPE objectType,
            String trustee,
            TRUSTEE_FORM trusteeForm,
            long accessRights,
            ACCESS_MODE accessMode,
            long inheritance) {
        if (objectName == null) {
            throw new NullPointerException("Invalid object name");
        }

        Pointer pOldDACL = new Pointer(new ACL());
        Pointer pNewDACL = new Pointer(new ACL());
        Pointer pSD = new Pointer(new SECURITY_DESCRIPTOR());

        // Get a pointer to the existing DACL.
        Function getNamedSecurityInfo = advApi32.getFunction("GetNamedSecurityInfoW");
        UInt32 resultValue = new UInt32();
        getNamedSecurityInfo.invoke(resultValue, new Parameter[]{
                new WideString(objectName),
                new Int(objectType.ordinal()),
                new Int(DACL_SECURITY_INFORMATION),
                new Pointer.Void(), // NULL
                new Pointer.Void(),  // NULL
                new Pointer(pOldDACL),
                new Pointer.Void(), // NULL
                new Pointer(pSD)});
        if (resultValue.getValue() != ERROR_SUCCESS) {
            throw new RuntimeException("GetNamedSecurityInfo Error: " + resultValue);
        }

        // Initialize an EXPLICIT_ACCESS structure for the new ACE.
        EXPLICIT_ACCESS ea = new EXPLICIT_ACCESS();
        ea.grfAccessPermissions.setValue(accessRights);
        ea.grfAccessMode.setValue(accessMode.ordinal());
        ea.grfInheritance.setValue(inheritance);
        ea.Trustee.TrusteeForm.setValue(trusteeForm.ordinal());
        ea.Trustee.ptstrName.setReferencedObject(new Str(trustee));

        // Create a new ACL that merges the new ACE
        // into the existing DACL.
        Function setEntriesInAcl = advApi32.getFunction("SetEntriesInAclW");
        setEntriesInAcl.invoke(resultValue, new Parameter[]{
                new Int(1),
                new Pointer(ea),
                pOldDACL,
                new Pointer(pNewDACL)
        });

        if (resultValue.getValue() != ERROR_SUCCESS) {
            throw new RuntimeException("SetEntriesInAcl Error: " + resultValue);
        }

        // Attach the new ACL as the object's DACL.
        Function setNamedSecurityInfo = advApi32.getFunction("SetNamedSecurityInfoW");
        setNamedSecurityInfo.invoke(resultValue, new Parameter[]{
                new Pointer(new WideString(objectName)),
                new Int(objectType.ordinal()),
                new Int(DACL_SECURITY_INFORMATION),
                new Pointer.Void(), // NULL
                new Pointer.Void(), // NULL
                pNewDACL,
                new Pointer.Void(), // NULL
        });

        if (resultValue.getValue() != ERROR_SUCCESS) {
            throw new RuntimeException("SetNamedSecurityInfo Error: " + resultValue);
        }
    }


    static final long GENERIC_READ = 0x80000000L;
    static final long GENERIC_WRITE = 0x40000000L;
    static final long GENERIC_EXECUTE = 0x20000000L;
    static final long GENERIC_ALL = 0x10000000L;

    static final int NO_INHERITANCE = 0x0;
    static final int OBJECT_INHERIT_ACE = 0x1;
    static final int CONTAINER_INHERIT_ACE = 0x2;
    static final int NO_PROPAGATE_INHERIT_ACE = 0x4;
    static final int INHERIT_ONLY_ACE = 0x8;
    static final int INHERITED_ACE = 0x10;
    static final int VALID_INHERIT_FLAGS = 0x1F;


    public static void main(String[] args) {
        addAceToObjectsSecurityDescriptor("d:\\MyFolder",
                SE_OBJECT_TYPE.SE_FILE_OBJECT,
                "Users",
                TRUSTEE_FORM.TRUSTEE_IS_NAME,
                GENERIC_READ,
                ACCESS_MODE.GRANT_ACCESS,
                CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE);

        System.out.println("Done!");
    }
}