Unmanaged memory issue causing by Authz.dll












0















I have situation where I need to traverse filesystem and calculate effective permission of users on files and directories and for that I'm using code the shown below. The issue is this code is creating managed memory up to 2 GB in my case.



I've tried every possible thing to fix the memory leak as shown in code but still un-managed memory is growing. Please help me with the code below. I tried to dispose the object and also by using authz memory release methods but nothing works for me.



using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Security.Principal;

namespace EffectiveRightsUsingAuthzAPI
{
public class Helper:IDisposable
{
[DllImport("advapi32.dll", SetLastError = true)]
static extern uint GetEffectiveRightsFromAcl(IntPtr pDacl, ref TRUSTEE pTrustee, ref ACCESS_MASK pAccessRights);

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 4)]
struct TRUSTEE
{
IntPtr pMultipleTrustee; // must be null
public int MultipleTrusteeOperation;
public TRUSTEE_FORM TrusteeForm;
public TRUSTEE_TYPE TrusteeType;
[MarshalAs(UnmanagedType.LPStr)]
public string ptstrName;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 4)]
public struct LUID
{
public uint LowPart;
public int HighPart;
}

[StructLayout(LayoutKind.Sequential)]
public struct AUTHZ_ACCESS_REQUEST
{
public int DesiredAccess;
public byte PrincipalSelfSid;
public OBJECT_TYPE_LIST ObjectTypeList;
public int ObjectTypeListLength;
public IntPtr OptionalArguments;
};
[StructLayout(LayoutKind.Sequential)]
public struct OBJECT_TYPE_LIST
{
OBJECT_TYPE_LEVEL Level;
int Sbz;
IntPtr ObjectType;
};

[StructLayout(LayoutKind.Sequential)]
public struct AUTHZ_ACCESS_REPLY
{
public int ResultListLength;
public IntPtr GrantedAccessMask;
public IntPtr SaclEvaluationResults;
public IntPtr Error;
};

public enum OBJECT_TYPE_LEVEL : int
{
ACCESS_OBJECT_GUID = 0,
ACCESS_PROPERTY_SET_GUID = 1,
ACCESS_PROPERTY_GUID = 2,
ACCESS_MAX_LEVEL = 4
};
enum TRUSTEE_FORM
{
TRUSTEE_IS_SID,
TRUSTEE_IS_NAME,
TRUSTEE_BAD_FORM,
TRUSTEE_IS_OBJECTS_AND_SID,
TRUSTEE_IS_OBJECTS_AND_NAME
}

enum AUTHZ_RM_FLAG : uint
{
AUTHZ_RM_FLAG_NO_AUDIT = 1,
AUTHZ_RM_FLAG_INITIALIZE_UNDER_IMPERSONATION = 2,
AUTHZ_RM_FLAG_NO_CENTRAL_ACCESS_POLICIES = 4,
}

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
}

[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
static extern uint GetNamedSecurityInfo(
string pObjectName,
SE_OBJECT_TYPE ObjectType,
SECURITY_INFORMATION SecurityInfo,
out IntPtr pSidOwner,
out IntPtr pSidGroup,
out IntPtr pDacl,
out IntPtr pSacl,
out IntPtr pSecurityDescriptor);
[DllImport("authz.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall, EntryPoint = "AuthzInitializeContextFromSid", CharSet = CharSet.Unicode)]
static extern public bool AuthzInitializeContextFromSid(
int Flags,
IntPtr UserSid,
IntPtr AuthzResourceManager,
IntPtr pExpirationTime,
LUID Identitifier,
IntPtr DynamicGroupArgs,
out IntPtr pAuthzClientContext
);



[DllImport("authz.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall, EntryPoint = "AuthzInitializeResourceManager", CharSet = CharSet.Unicode)]
static extern public bool AuthzInitializeResourceManager(
int flags,
IntPtr pfnAccessCheck,
IntPtr pfnComputeDynamicGroups,
IntPtr pfnFreeDynamicGroups,
string name,
out IntPtr rm
);
[DllImport("authz.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall, EntryPoint = "AuthzFreeResourceManager", CharSet = CharSet.Unicode)]
static extern public bool AuthzFreeResourceManager(IntPtr hManager);

[DllImport("authz.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall, EntryPoint = "AuthzFreeHandle", CharSet = CharSet.Unicode)]
static extern public bool AuthzFreeHandle(IntPtr hAccessCheckResults);

[DllImport("authz.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall, EntryPoint = "AuthzFreeContext", CharSet = CharSet.Unicode)]
static extern public bool AuthzFreeContext(IntPtr hAuthzClientContext);
[DllImport("authz.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall, EntryPoint = "AuthzFreeCentralAccessPolicyCache", CharSet = CharSet.Unicode)]
static extern public bool AuthzFreeCentralAccessPolicyCache();

[DllImport("authz.dll", EntryPoint = "AuthzAccessCheck", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
private static extern bool AuthzAccessCheck(int flags,
IntPtr hAuthzClientContext,
ref AUTHZ_ACCESS_REQUEST pRequest,
IntPtr AuditEvent,
IntPtr pSecurityDescriptor,
byte OptionalSecurityDescriptorArray,
int OptionalSecurityDescriptorCount,
ref AUTHZ_ACCESS_REPLY pReply,
out IntPtr phAccessCheckResults);

enum ACCESS_MASK : uint
{
FILE_TRAVERSE = 0x20,
FILE_LIST_DIRECTORY = 0x1,
FILE_READ_DATA = 0x1,
FILE_READ_ATTRIBUTES = 0x80,
FILE_READ_EA = 0x8,
FILE_ADD_FILE = 0x2,
FILE_WRITE_DATA = 0x2,
FILE_ADD_SUBDIRECTORY = 0x4,
FILE_APPEND_DATA = 0x4,
FILE_WRITE_ATTRIBUTES = 0x100,
FILE_WRITE_EA = 0x10,
FILE_DELETE_CHILD = 0x40,
DELETE = 0x10000,
READ_CONTROL = 0x20000,
WRITE_DAC = 0x40000,
WRITE_OWNER = 0x80000,


////////FILE_EXECUTE =0x20,
}

[Flags]
enum SECURITY_INFORMATION : uint
{
OWNER_SECURITY_INFORMATION = 0x00000001,
GROUP_SECURITY_INFORMATION = 0x00000002,
DACL_SECURITY_INFORMATION = 0x00000004,
SACL_SECURITY_INFORMATION = 0x00000008,
UNPROTECTED_SACL_SECURITY_INFORMATION = 0x10000000,
UNPROTECTED_DACL_SECURITY_INFORMATION = 0x20000000,
PROTECTED_SACL_SECURITY_INFORMATION = 0x40000000,
PROTECTED_DACL_SECURITY_INFORMATION = 0x80000000
}

enum SE_OBJECT_TYPE
{
SE_UNKNOWN_OBJECT_TYPE = 0,
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 PermissionValues GetEffectivePermissions(string UserName, string Path, out string object_sid)
{
List<string> result = new List<string>();
IntPtr pSidOwner, pSidGroup, pDacl, pSacl, pSecurityDescriptor;
ACCESS_MASK mask = new ACCESS_MASK();
uint ret = GetNamedSecurityInfo(Path,
SE_OBJECT_TYPE.SE_FILE_OBJECT,
SECURITY_INFORMATION.DACL_SECURITY_INFORMATION | SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION | SECURITY_INFORMATION.GROUP_SECURITY_INFORMATION,
out pSidOwner, out pSidGroup, out pDacl, out pSacl, out pSecurityDescriptor);

IntPtr hManager = IntPtr.Zero;

bool f = AuthzInitializeResourceManager(1, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, null, out hManager);

NTAccount ac = new NTAccount(UserName);
SecurityIdentifier sid;
if (Imanami.PermissionProvider.FileSystem.Helper.isObjectSID(UserName))
sid = new SecurityIdentifier(UserName);
else
sid = (SecurityIdentifier)ac.Translate(typeof(SecurityIdentifier));
object_sid = sid.Value;
byte bytes = new byte[sid.BinaryLength];
sid.GetBinaryForm(bytes, 0);
String _psUserSid = "";
foreach (byte si in bytes)
{
_psUserSid += si;
}

LUID unusedSid = new LUID();
IntPtr UserSid = Marshal.AllocHGlobal(bytes.Length);
Marshal.Copy(bytes, 0, UserSid, bytes.Length);
IntPtr pClientContext = IntPtr.Zero;

if (f)
{
f = AuthzInitializeContextFromSid(0, UserSid, hManager, IntPtr.Zero, unusedSid, IntPtr.Zero, out pClientContext);


AUTHZ_ACCESS_REQUEST request = new AUTHZ_ACCESS_REQUEST();
request.DesiredAccess = 0x02000000;
request.PrincipalSelfSid = null;
request.ObjectTypeList = null;
request.ObjectTypeListLength = 0;
request.OptionalArguments = IntPtr.Zero;

AUTHZ_ACCESS_REPLY reply = new AUTHZ_ACCESS_REPLY();
reply.GrantedAccessMask = IntPtr.Zero;
reply.ResultListLength = 0;
reply.SaclEvaluationResults = IntPtr.Zero;
IntPtr AccessReply = IntPtr.Zero;
reply.Error = Marshal.AllocHGlobal(1020);
reply.GrantedAccessMask = Marshal.AllocHGlobal(sizeof(uint));
reply.ResultListLength = 1;
int i = 0;
Dictionary<String, String> rightsmap = new Dictionary<String, String>();
List<string> effectivePermissionList = new List<string>();
string rights = new string[14] { "Full Control", "Traverse Folder / execute file", "List folder / read data", "Read attributes", "Read extended attributes", "Create files / write files", "Create folders / append data", "Write attributes", "Write extended attributes", "Delete subfolders and files", "Delete", "Read permission", "Change permission", "Take ownership" };
rightsmap.Add("FILE_TRAVERSE", "Traverse Folder / execute file");
rightsmap.Add("FILE_LIST_DIRECTORY", "List folder / read data");
rightsmap.Add("FILE_READ_DATA", "List folder / read data");
rightsmap.Add("FILE_READ_ATTRIBUTES", "Read attributes");
rightsmap.Add("FILE_READ_EA", "Read extended attributes");
rightsmap.Add("FILE_ADD_FILE", "Create files / write files");
rightsmap.Add("FILE_WRITE_DATA", "Create files / write files");
rightsmap.Add("FILE_ADD_SUBDIRECTORY", "Create folders / append data");
rightsmap.Add("FILE_APPEND_DATA", "Create folders / append data");
rightsmap.Add("FILE_WRITE_ATTRIBUTES", "Write attributes");
rightsmap.Add("FILE_WRITE_EA", "Write extended attributes");
rightsmap.Add("FILE_DELETE_CHILD", "Delete subfolders and files");
rightsmap.Add("DELETE", "Delete");
rightsmap.Add("READ_CONTROL", "Read permission");
rightsmap.Add("WRITE_DAC", "Change permission");
rightsmap.Add("WRITE_OWNER", "Take ownership");


f = AuthzAccessCheck(0, pClientContext, ref request, IntPtr.Zero, pSecurityDescriptor, null, 0, ref reply, out AccessReply);
if (f)
{
int granted_access = Marshal.ReadInt32(reply.GrantedAccessMask);

mask = (ACCESS_MASK)granted_access;

foreach (ACCESS_MASK item in Enum.GetValues(typeof(ACCESS_MASK)))
{
if ((mask & item) == item)
{
effectivePermissionList.Add(rightsmap[item.ToString()]);
i++;
}

}
}
//Clear Memory
{
Marshal.FreeHGlobal(reply.GrantedAccessMask);
if (reply.Error != IntPtr.Zero)
Marshal.FreeHGlobal(reply.Error);
if (UserSid != IntPtr.Zero)
Marshal.FreeHGlobal(UserSid);
if (pSidOwner != IntPtr.Zero)
Marshal.Release(pSidOwner);
if (pSidGroup != IntPtr.Zero)
Marshal.Release(pSidGroup);
if (pDacl != IntPtr.Zero)
Marshal.Release(pDacl);
if (pSacl != IntPtr.Zero)
Marshal.Release(pSacl);
if (pSecurityDescriptor != IntPtr.Zero)
Marshal.Release(pSecurityDescriptor);
if (reply.SaclEvaluationResults != IntPtr.Zero)
Marshal.Release(reply.SaclEvaluationResults);
if (request.OptionalArguments != IntPtr.Zero)
Marshal.Release(request.OptionalArguments);

if (AccessReply != IntPtr.Zero)
AuthzFreeHandle(AccessReply);
if (hManager != IntPtr.Zero)
AuthzFreeResourceManager(hManager);
if (pClientContext != IntPtr.Zero)
AuthzFreeContext(pClientContext);
AuthzFreeCentralAccessPolicyCache();
}

if (i == 16)
{
effectivePermissionList.Insert(0, "Full Control");
return PermissionValues.FULL_CONTROL;
}
PermissionValues per = PermissionValues.NONE;
foreach (string r in effectivePermissionList)
{

switch (r)
{
case "Traverse Folder / execute file":
per |= PermissionValues.FILE_TRAVERSE;
break;
case "List folder / read data":
per |= PermissionValues.FILE_LIST_DIRECTORY;
break;
case "Read attributes":
per |= PermissionValues.FILE_READ_ATTRIBUTES;
break;
case "Read extended attributes":
per |= PermissionValues.FILE_READ_EA;
break;
case "Create files / write files":
per |= PermissionValues.FILE_ADD_FILE;
break;
case "Create files / write files":
per |= PermissionValues.FILE_WRITE_DATA;
break;
case "Create folders / append data":
per |= (PermissionValues.FILE_ADD_SUBDIRECTORY | PermissionValues.FILE_APPEND_DATA);
break;
case "Write attributes":
per |= PermissionValues.FILE_WRITE_ATTRIBUTES;
break;
case "Write extended attributes":
per |= PermissionValues.FILE_WRITE_EA;
break;
case "Delete subfolders and files":
per |= PermissionValues.FILE_DELETE_CHILD;
break;
case "Delete":
per |= PermissionValues.DELETE;
break;
case "Read permission":
per |= PermissionValues.READ_CONTROL;
break;
case "Change permission":
per |= PermissionValues.WRITE_DAC;
break;
case "Take ownership":
per |= PermissionValues.WRITE_OWNER;
break;
}
}

//foreach(var obj in request.ObjectTypeList)
//{

//}
return per;

}

return PermissionValues.NONE;

}

public void Dispose()
{
GC.SuppressFinalize(this);
}
}
}









share|improve this question





























    0















    I have situation where I need to traverse filesystem and calculate effective permission of users on files and directories and for that I'm using code the shown below. The issue is this code is creating managed memory up to 2 GB in my case.



    I've tried every possible thing to fix the memory leak as shown in code but still un-managed memory is growing. Please help me with the code below. I tried to dispose the object and also by using authz memory release methods but nothing works for me.



    using System;
    using System.Collections.Generic;
    using System.Runtime.InteropServices;
    using System.Security.Principal;

    namespace EffectiveRightsUsingAuthzAPI
    {
    public class Helper:IDisposable
    {
    [DllImport("advapi32.dll", SetLastError = true)]
    static extern uint GetEffectiveRightsFromAcl(IntPtr pDacl, ref TRUSTEE pTrustee, ref ACCESS_MASK pAccessRights);

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 4)]
    struct TRUSTEE
    {
    IntPtr pMultipleTrustee; // must be null
    public int MultipleTrusteeOperation;
    public TRUSTEE_FORM TrusteeForm;
    public TRUSTEE_TYPE TrusteeType;
    [MarshalAs(UnmanagedType.LPStr)]
    public string ptstrName;
    }
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 4)]
    public struct LUID
    {
    public uint LowPart;
    public int HighPart;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct AUTHZ_ACCESS_REQUEST
    {
    public int DesiredAccess;
    public byte PrincipalSelfSid;
    public OBJECT_TYPE_LIST ObjectTypeList;
    public int ObjectTypeListLength;
    public IntPtr OptionalArguments;
    };
    [StructLayout(LayoutKind.Sequential)]
    public struct OBJECT_TYPE_LIST
    {
    OBJECT_TYPE_LEVEL Level;
    int Sbz;
    IntPtr ObjectType;
    };

    [StructLayout(LayoutKind.Sequential)]
    public struct AUTHZ_ACCESS_REPLY
    {
    public int ResultListLength;
    public IntPtr GrantedAccessMask;
    public IntPtr SaclEvaluationResults;
    public IntPtr Error;
    };

    public enum OBJECT_TYPE_LEVEL : int
    {
    ACCESS_OBJECT_GUID = 0,
    ACCESS_PROPERTY_SET_GUID = 1,
    ACCESS_PROPERTY_GUID = 2,
    ACCESS_MAX_LEVEL = 4
    };
    enum TRUSTEE_FORM
    {
    TRUSTEE_IS_SID,
    TRUSTEE_IS_NAME,
    TRUSTEE_BAD_FORM,
    TRUSTEE_IS_OBJECTS_AND_SID,
    TRUSTEE_IS_OBJECTS_AND_NAME
    }

    enum AUTHZ_RM_FLAG : uint
    {
    AUTHZ_RM_FLAG_NO_AUDIT = 1,
    AUTHZ_RM_FLAG_INITIALIZE_UNDER_IMPERSONATION = 2,
    AUTHZ_RM_FLAG_NO_CENTRAL_ACCESS_POLICIES = 4,
    }

    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
    }

    [DllImport("advapi32.dll", CharSet = CharSet.Auto)]
    static extern uint GetNamedSecurityInfo(
    string pObjectName,
    SE_OBJECT_TYPE ObjectType,
    SECURITY_INFORMATION SecurityInfo,
    out IntPtr pSidOwner,
    out IntPtr pSidGroup,
    out IntPtr pDacl,
    out IntPtr pSacl,
    out IntPtr pSecurityDescriptor);
    [DllImport("authz.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall, EntryPoint = "AuthzInitializeContextFromSid", CharSet = CharSet.Unicode)]
    static extern public bool AuthzInitializeContextFromSid(
    int Flags,
    IntPtr UserSid,
    IntPtr AuthzResourceManager,
    IntPtr pExpirationTime,
    LUID Identitifier,
    IntPtr DynamicGroupArgs,
    out IntPtr pAuthzClientContext
    );



    [DllImport("authz.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall, EntryPoint = "AuthzInitializeResourceManager", CharSet = CharSet.Unicode)]
    static extern public bool AuthzInitializeResourceManager(
    int flags,
    IntPtr pfnAccessCheck,
    IntPtr pfnComputeDynamicGroups,
    IntPtr pfnFreeDynamicGroups,
    string name,
    out IntPtr rm
    );
    [DllImport("authz.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall, EntryPoint = "AuthzFreeResourceManager", CharSet = CharSet.Unicode)]
    static extern public bool AuthzFreeResourceManager(IntPtr hManager);

    [DllImport("authz.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall, EntryPoint = "AuthzFreeHandle", CharSet = CharSet.Unicode)]
    static extern public bool AuthzFreeHandle(IntPtr hAccessCheckResults);

    [DllImport("authz.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall, EntryPoint = "AuthzFreeContext", CharSet = CharSet.Unicode)]
    static extern public bool AuthzFreeContext(IntPtr hAuthzClientContext);
    [DllImport("authz.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall, EntryPoint = "AuthzFreeCentralAccessPolicyCache", CharSet = CharSet.Unicode)]
    static extern public bool AuthzFreeCentralAccessPolicyCache();

    [DllImport("authz.dll", EntryPoint = "AuthzAccessCheck", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
    private static extern bool AuthzAccessCheck(int flags,
    IntPtr hAuthzClientContext,
    ref AUTHZ_ACCESS_REQUEST pRequest,
    IntPtr AuditEvent,
    IntPtr pSecurityDescriptor,
    byte OptionalSecurityDescriptorArray,
    int OptionalSecurityDescriptorCount,
    ref AUTHZ_ACCESS_REPLY pReply,
    out IntPtr phAccessCheckResults);

    enum ACCESS_MASK : uint
    {
    FILE_TRAVERSE = 0x20,
    FILE_LIST_DIRECTORY = 0x1,
    FILE_READ_DATA = 0x1,
    FILE_READ_ATTRIBUTES = 0x80,
    FILE_READ_EA = 0x8,
    FILE_ADD_FILE = 0x2,
    FILE_WRITE_DATA = 0x2,
    FILE_ADD_SUBDIRECTORY = 0x4,
    FILE_APPEND_DATA = 0x4,
    FILE_WRITE_ATTRIBUTES = 0x100,
    FILE_WRITE_EA = 0x10,
    FILE_DELETE_CHILD = 0x40,
    DELETE = 0x10000,
    READ_CONTROL = 0x20000,
    WRITE_DAC = 0x40000,
    WRITE_OWNER = 0x80000,


    ////////FILE_EXECUTE =0x20,
    }

    [Flags]
    enum SECURITY_INFORMATION : uint
    {
    OWNER_SECURITY_INFORMATION = 0x00000001,
    GROUP_SECURITY_INFORMATION = 0x00000002,
    DACL_SECURITY_INFORMATION = 0x00000004,
    SACL_SECURITY_INFORMATION = 0x00000008,
    UNPROTECTED_SACL_SECURITY_INFORMATION = 0x10000000,
    UNPROTECTED_DACL_SECURITY_INFORMATION = 0x20000000,
    PROTECTED_SACL_SECURITY_INFORMATION = 0x40000000,
    PROTECTED_DACL_SECURITY_INFORMATION = 0x80000000
    }

    enum SE_OBJECT_TYPE
    {
    SE_UNKNOWN_OBJECT_TYPE = 0,
    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 PermissionValues GetEffectivePermissions(string UserName, string Path, out string object_sid)
    {
    List<string> result = new List<string>();
    IntPtr pSidOwner, pSidGroup, pDacl, pSacl, pSecurityDescriptor;
    ACCESS_MASK mask = new ACCESS_MASK();
    uint ret = GetNamedSecurityInfo(Path,
    SE_OBJECT_TYPE.SE_FILE_OBJECT,
    SECURITY_INFORMATION.DACL_SECURITY_INFORMATION | SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION | SECURITY_INFORMATION.GROUP_SECURITY_INFORMATION,
    out pSidOwner, out pSidGroup, out pDacl, out pSacl, out pSecurityDescriptor);

    IntPtr hManager = IntPtr.Zero;

    bool f = AuthzInitializeResourceManager(1, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, null, out hManager);

    NTAccount ac = new NTAccount(UserName);
    SecurityIdentifier sid;
    if (Imanami.PermissionProvider.FileSystem.Helper.isObjectSID(UserName))
    sid = new SecurityIdentifier(UserName);
    else
    sid = (SecurityIdentifier)ac.Translate(typeof(SecurityIdentifier));
    object_sid = sid.Value;
    byte bytes = new byte[sid.BinaryLength];
    sid.GetBinaryForm(bytes, 0);
    String _psUserSid = "";
    foreach (byte si in bytes)
    {
    _psUserSid += si;
    }

    LUID unusedSid = new LUID();
    IntPtr UserSid = Marshal.AllocHGlobal(bytes.Length);
    Marshal.Copy(bytes, 0, UserSid, bytes.Length);
    IntPtr pClientContext = IntPtr.Zero;

    if (f)
    {
    f = AuthzInitializeContextFromSid(0, UserSid, hManager, IntPtr.Zero, unusedSid, IntPtr.Zero, out pClientContext);


    AUTHZ_ACCESS_REQUEST request = new AUTHZ_ACCESS_REQUEST();
    request.DesiredAccess = 0x02000000;
    request.PrincipalSelfSid = null;
    request.ObjectTypeList = null;
    request.ObjectTypeListLength = 0;
    request.OptionalArguments = IntPtr.Zero;

    AUTHZ_ACCESS_REPLY reply = new AUTHZ_ACCESS_REPLY();
    reply.GrantedAccessMask = IntPtr.Zero;
    reply.ResultListLength = 0;
    reply.SaclEvaluationResults = IntPtr.Zero;
    IntPtr AccessReply = IntPtr.Zero;
    reply.Error = Marshal.AllocHGlobal(1020);
    reply.GrantedAccessMask = Marshal.AllocHGlobal(sizeof(uint));
    reply.ResultListLength = 1;
    int i = 0;
    Dictionary<String, String> rightsmap = new Dictionary<String, String>();
    List<string> effectivePermissionList = new List<string>();
    string rights = new string[14] { "Full Control", "Traverse Folder / execute file", "List folder / read data", "Read attributes", "Read extended attributes", "Create files / write files", "Create folders / append data", "Write attributes", "Write extended attributes", "Delete subfolders and files", "Delete", "Read permission", "Change permission", "Take ownership" };
    rightsmap.Add("FILE_TRAVERSE", "Traverse Folder / execute file");
    rightsmap.Add("FILE_LIST_DIRECTORY", "List folder / read data");
    rightsmap.Add("FILE_READ_DATA", "List folder / read data");
    rightsmap.Add("FILE_READ_ATTRIBUTES", "Read attributes");
    rightsmap.Add("FILE_READ_EA", "Read extended attributes");
    rightsmap.Add("FILE_ADD_FILE", "Create files / write files");
    rightsmap.Add("FILE_WRITE_DATA", "Create files / write files");
    rightsmap.Add("FILE_ADD_SUBDIRECTORY", "Create folders / append data");
    rightsmap.Add("FILE_APPEND_DATA", "Create folders / append data");
    rightsmap.Add("FILE_WRITE_ATTRIBUTES", "Write attributes");
    rightsmap.Add("FILE_WRITE_EA", "Write extended attributes");
    rightsmap.Add("FILE_DELETE_CHILD", "Delete subfolders and files");
    rightsmap.Add("DELETE", "Delete");
    rightsmap.Add("READ_CONTROL", "Read permission");
    rightsmap.Add("WRITE_DAC", "Change permission");
    rightsmap.Add("WRITE_OWNER", "Take ownership");


    f = AuthzAccessCheck(0, pClientContext, ref request, IntPtr.Zero, pSecurityDescriptor, null, 0, ref reply, out AccessReply);
    if (f)
    {
    int granted_access = Marshal.ReadInt32(reply.GrantedAccessMask);

    mask = (ACCESS_MASK)granted_access;

    foreach (ACCESS_MASK item in Enum.GetValues(typeof(ACCESS_MASK)))
    {
    if ((mask & item) == item)
    {
    effectivePermissionList.Add(rightsmap[item.ToString()]);
    i++;
    }

    }
    }
    //Clear Memory
    {
    Marshal.FreeHGlobal(reply.GrantedAccessMask);
    if (reply.Error != IntPtr.Zero)
    Marshal.FreeHGlobal(reply.Error);
    if (UserSid != IntPtr.Zero)
    Marshal.FreeHGlobal(UserSid);
    if (pSidOwner != IntPtr.Zero)
    Marshal.Release(pSidOwner);
    if (pSidGroup != IntPtr.Zero)
    Marshal.Release(pSidGroup);
    if (pDacl != IntPtr.Zero)
    Marshal.Release(pDacl);
    if (pSacl != IntPtr.Zero)
    Marshal.Release(pSacl);
    if (pSecurityDescriptor != IntPtr.Zero)
    Marshal.Release(pSecurityDescriptor);
    if (reply.SaclEvaluationResults != IntPtr.Zero)
    Marshal.Release(reply.SaclEvaluationResults);
    if (request.OptionalArguments != IntPtr.Zero)
    Marshal.Release(request.OptionalArguments);

    if (AccessReply != IntPtr.Zero)
    AuthzFreeHandle(AccessReply);
    if (hManager != IntPtr.Zero)
    AuthzFreeResourceManager(hManager);
    if (pClientContext != IntPtr.Zero)
    AuthzFreeContext(pClientContext);
    AuthzFreeCentralAccessPolicyCache();
    }

    if (i == 16)
    {
    effectivePermissionList.Insert(0, "Full Control");
    return PermissionValues.FULL_CONTROL;
    }
    PermissionValues per = PermissionValues.NONE;
    foreach (string r in effectivePermissionList)
    {

    switch (r)
    {
    case "Traverse Folder / execute file":
    per |= PermissionValues.FILE_TRAVERSE;
    break;
    case "List folder / read data":
    per |= PermissionValues.FILE_LIST_DIRECTORY;
    break;
    case "Read attributes":
    per |= PermissionValues.FILE_READ_ATTRIBUTES;
    break;
    case "Read extended attributes":
    per |= PermissionValues.FILE_READ_EA;
    break;
    case "Create files / write files":
    per |= PermissionValues.FILE_ADD_FILE;
    break;
    case "Create files / write files":
    per |= PermissionValues.FILE_WRITE_DATA;
    break;
    case "Create folders / append data":
    per |= (PermissionValues.FILE_ADD_SUBDIRECTORY | PermissionValues.FILE_APPEND_DATA);
    break;
    case "Write attributes":
    per |= PermissionValues.FILE_WRITE_ATTRIBUTES;
    break;
    case "Write extended attributes":
    per |= PermissionValues.FILE_WRITE_EA;
    break;
    case "Delete subfolders and files":
    per |= PermissionValues.FILE_DELETE_CHILD;
    break;
    case "Delete":
    per |= PermissionValues.DELETE;
    break;
    case "Read permission":
    per |= PermissionValues.READ_CONTROL;
    break;
    case "Change permission":
    per |= PermissionValues.WRITE_DAC;
    break;
    case "Take ownership":
    per |= PermissionValues.WRITE_OWNER;
    break;
    }
    }

    //foreach(var obj in request.ObjectTypeList)
    //{

    //}
    return per;

    }

    return PermissionValues.NONE;

    }

    public void Dispose()
    {
    GC.SuppressFinalize(this);
    }
    }
    }









    share|improve this question



























      0












      0








      0








      I have situation where I need to traverse filesystem and calculate effective permission of users on files and directories and for that I'm using code the shown below. The issue is this code is creating managed memory up to 2 GB in my case.



      I've tried every possible thing to fix the memory leak as shown in code but still un-managed memory is growing. Please help me with the code below. I tried to dispose the object and also by using authz memory release methods but nothing works for me.



      using System;
      using System.Collections.Generic;
      using System.Runtime.InteropServices;
      using System.Security.Principal;

      namespace EffectiveRightsUsingAuthzAPI
      {
      public class Helper:IDisposable
      {
      [DllImport("advapi32.dll", SetLastError = true)]
      static extern uint GetEffectiveRightsFromAcl(IntPtr pDacl, ref TRUSTEE pTrustee, ref ACCESS_MASK pAccessRights);

      [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 4)]
      struct TRUSTEE
      {
      IntPtr pMultipleTrustee; // must be null
      public int MultipleTrusteeOperation;
      public TRUSTEE_FORM TrusteeForm;
      public TRUSTEE_TYPE TrusteeType;
      [MarshalAs(UnmanagedType.LPStr)]
      public string ptstrName;
      }
      [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 4)]
      public struct LUID
      {
      public uint LowPart;
      public int HighPart;
      }

      [StructLayout(LayoutKind.Sequential)]
      public struct AUTHZ_ACCESS_REQUEST
      {
      public int DesiredAccess;
      public byte PrincipalSelfSid;
      public OBJECT_TYPE_LIST ObjectTypeList;
      public int ObjectTypeListLength;
      public IntPtr OptionalArguments;
      };
      [StructLayout(LayoutKind.Sequential)]
      public struct OBJECT_TYPE_LIST
      {
      OBJECT_TYPE_LEVEL Level;
      int Sbz;
      IntPtr ObjectType;
      };

      [StructLayout(LayoutKind.Sequential)]
      public struct AUTHZ_ACCESS_REPLY
      {
      public int ResultListLength;
      public IntPtr GrantedAccessMask;
      public IntPtr SaclEvaluationResults;
      public IntPtr Error;
      };

      public enum OBJECT_TYPE_LEVEL : int
      {
      ACCESS_OBJECT_GUID = 0,
      ACCESS_PROPERTY_SET_GUID = 1,
      ACCESS_PROPERTY_GUID = 2,
      ACCESS_MAX_LEVEL = 4
      };
      enum TRUSTEE_FORM
      {
      TRUSTEE_IS_SID,
      TRUSTEE_IS_NAME,
      TRUSTEE_BAD_FORM,
      TRUSTEE_IS_OBJECTS_AND_SID,
      TRUSTEE_IS_OBJECTS_AND_NAME
      }

      enum AUTHZ_RM_FLAG : uint
      {
      AUTHZ_RM_FLAG_NO_AUDIT = 1,
      AUTHZ_RM_FLAG_INITIALIZE_UNDER_IMPERSONATION = 2,
      AUTHZ_RM_FLAG_NO_CENTRAL_ACCESS_POLICIES = 4,
      }

      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
      }

      [DllImport("advapi32.dll", CharSet = CharSet.Auto)]
      static extern uint GetNamedSecurityInfo(
      string pObjectName,
      SE_OBJECT_TYPE ObjectType,
      SECURITY_INFORMATION SecurityInfo,
      out IntPtr pSidOwner,
      out IntPtr pSidGroup,
      out IntPtr pDacl,
      out IntPtr pSacl,
      out IntPtr pSecurityDescriptor);
      [DllImport("authz.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall, EntryPoint = "AuthzInitializeContextFromSid", CharSet = CharSet.Unicode)]
      static extern public bool AuthzInitializeContextFromSid(
      int Flags,
      IntPtr UserSid,
      IntPtr AuthzResourceManager,
      IntPtr pExpirationTime,
      LUID Identitifier,
      IntPtr DynamicGroupArgs,
      out IntPtr pAuthzClientContext
      );



      [DllImport("authz.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall, EntryPoint = "AuthzInitializeResourceManager", CharSet = CharSet.Unicode)]
      static extern public bool AuthzInitializeResourceManager(
      int flags,
      IntPtr pfnAccessCheck,
      IntPtr pfnComputeDynamicGroups,
      IntPtr pfnFreeDynamicGroups,
      string name,
      out IntPtr rm
      );
      [DllImport("authz.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall, EntryPoint = "AuthzFreeResourceManager", CharSet = CharSet.Unicode)]
      static extern public bool AuthzFreeResourceManager(IntPtr hManager);

      [DllImport("authz.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall, EntryPoint = "AuthzFreeHandle", CharSet = CharSet.Unicode)]
      static extern public bool AuthzFreeHandle(IntPtr hAccessCheckResults);

      [DllImport("authz.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall, EntryPoint = "AuthzFreeContext", CharSet = CharSet.Unicode)]
      static extern public bool AuthzFreeContext(IntPtr hAuthzClientContext);
      [DllImport("authz.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall, EntryPoint = "AuthzFreeCentralAccessPolicyCache", CharSet = CharSet.Unicode)]
      static extern public bool AuthzFreeCentralAccessPolicyCache();

      [DllImport("authz.dll", EntryPoint = "AuthzAccessCheck", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
      private static extern bool AuthzAccessCheck(int flags,
      IntPtr hAuthzClientContext,
      ref AUTHZ_ACCESS_REQUEST pRequest,
      IntPtr AuditEvent,
      IntPtr pSecurityDescriptor,
      byte OptionalSecurityDescriptorArray,
      int OptionalSecurityDescriptorCount,
      ref AUTHZ_ACCESS_REPLY pReply,
      out IntPtr phAccessCheckResults);

      enum ACCESS_MASK : uint
      {
      FILE_TRAVERSE = 0x20,
      FILE_LIST_DIRECTORY = 0x1,
      FILE_READ_DATA = 0x1,
      FILE_READ_ATTRIBUTES = 0x80,
      FILE_READ_EA = 0x8,
      FILE_ADD_FILE = 0x2,
      FILE_WRITE_DATA = 0x2,
      FILE_ADD_SUBDIRECTORY = 0x4,
      FILE_APPEND_DATA = 0x4,
      FILE_WRITE_ATTRIBUTES = 0x100,
      FILE_WRITE_EA = 0x10,
      FILE_DELETE_CHILD = 0x40,
      DELETE = 0x10000,
      READ_CONTROL = 0x20000,
      WRITE_DAC = 0x40000,
      WRITE_OWNER = 0x80000,


      ////////FILE_EXECUTE =0x20,
      }

      [Flags]
      enum SECURITY_INFORMATION : uint
      {
      OWNER_SECURITY_INFORMATION = 0x00000001,
      GROUP_SECURITY_INFORMATION = 0x00000002,
      DACL_SECURITY_INFORMATION = 0x00000004,
      SACL_SECURITY_INFORMATION = 0x00000008,
      UNPROTECTED_SACL_SECURITY_INFORMATION = 0x10000000,
      UNPROTECTED_DACL_SECURITY_INFORMATION = 0x20000000,
      PROTECTED_SACL_SECURITY_INFORMATION = 0x40000000,
      PROTECTED_DACL_SECURITY_INFORMATION = 0x80000000
      }

      enum SE_OBJECT_TYPE
      {
      SE_UNKNOWN_OBJECT_TYPE = 0,
      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 PermissionValues GetEffectivePermissions(string UserName, string Path, out string object_sid)
      {
      List<string> result = new List<string>();
      IntPtr pSidOwner, pSidGroup, pDacl, pSacl, pSecurityDescriptor;
      ACCESS_MASK mask = new ACCESS_MASK();
      uint ret = GetNamedSecurityInfo(Path,
      SE_OBJECT_TYPE.SE_FILE_OBJECT,
      SECURITY_INFORMATION.DACL_SECURITY_INFORMATION | SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION | SECURITY_INFORMATION.GROUP_SECURITY_INFORMATION,
      out pSidOwner, out pSidGroup, out pDacl, out pSacl, out pSecurityDescriptor);

      IntPtr hManager = IntPtr.Zero;

      bool f = AuthzInitializeResourceManager(1, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, null, out hManager);

      NTAccount ac = new NTAccount(UserName);
      SecurityIdentifier sid;
      if (Imanami.PermissionProvider.FileSystem.Helper.isObjectSID(UserName))
      sid = new SecurityIdentifier(UserName);
      else
      sid = (SecurityIdentifier)ac.Translate(typeof(SecurityIdentifier));
      object_sid = sid.Value;
      byte bytes = new byte[sid.BinaryLength];
      sid.GetBinaryForm(bytes, 0);
      String _psUserSid = "";
      foreach (byte si in bytes)
      {
      _psUserSid += si;
      }

      LUID unusedSid = new LUID();
      IntPtr UserSid = Marshal.AllocHGlobal(bytes.Length);
      Marshal.Copy(bytes, 0, UserSid, bytes.Length);
      IntPtr pClientContext = IntPtr.Zero;

      if (f)
      {
      f = AuthzInitializeContextFromSid(0, UserSid, hManager, IntPtr.Zero, unusedSid, IntPtr.Zero, out pClientContext);


      AUTHZ_ACCESS_REQUEST request = new AUTHZ_ACCESS_REQUEST();
      request.DesiredAccess = 0x02000000;
      request.PrincipalSelfSid = null;
      request.ObjectTypeList = null;
      request.ObjectTypeListLength = 0;
      request.OptionalArguments = IntPtr.Zero;

      AUTHZ_ACCESS_REPLY reply = new AUTHZ_ACCESS_REPLY();
      reply.GrantedAccessMask = IntPtr.Zero;
      reply.ResultListLength = 0;
      reply.SaclEvaluationResults = IntPtr.Zero;
      IntPtr AccessReply = IntPtr.Zero;
      reply.Error = Marshal.AllocHGlobal(1020);
      reply.GrantedAccessMask = Marshal.AllocHGlobal(sizeof(uint));
      reply.ResultListLength = 1;
      int i = 0;
      Dictionary<String, String> rightsmap = new Dictionary<String, String>();
      List<string> effectivePermissionList = new List<string>();
      string rights = new string[14] { "Full Control", "Traverse Folder / execute file", "List folder / read data", "Read attributes", "Read extended attributes", "Create files / write files", "Create folders / append data", "Write attributes", "Write extended attributes", "Delete subfolders and files", "Delete", "Read permission", "Change permission", "Take ownership" };
      rightsmap.Add("FILE_TRAVERSE", "Traverse Folder / execute file");
      rightsmap.Add("FILE_LIST_DIRECTORY", "List folder / read data");
      rightsmap.Add("FILE_READ_DATA", "List folder / read data");
      rightsmap.Add("FILE_READ_ATTRIBUTES", "Read attributes");
      rightsmap.Add("FILE_READ_EA", "Read extended attributes");
      rightsmap.Add("FILE_ADD_FILE", "Create files / write files");
      rightsmap.Add("FILE_WRITE_DATA", "Create files / write files");
      rightsmap.Add("FILE_ADD_SUBDIRECTORY", "Create folders / append data");
      rightsmap.Add("FILE_APPEND_DATA", "Create folders / append data");
      rightsmap.Add("FILE_WRITE_ATTRIBUTES", "Write attributes");
      rightsmap.Add("FILE_WRITE_EA", "Write extended attributes");
      rightsmap.Add("FILE_DELETE_CHILD", "Delete subfolders and files");
      rightsmap.Add("DELETE", "Delete");
      rightsmap.Add("READ_CONTROL", "Read permission");
      rightsmap.Add("WRITE_DAC", "Change permission");
      rightsmap.Add("WRITE_OWNER", "Take ownership");


      f = AuthzAccessCheck(0, pClientContext, ref request, IntPtr.Zero, pSecurityDescriptor, null, 0, ref reply, out AccessReply);
      if (f)
      {
      int granted_access = Marshal.ReadInt32(reply.GrantedAccessMask);

      mask = (ACCESS_MASK)granted_access;

      foreach (ACCESS_MASK item in Enum.GetValues(typeof(ACCESS_MASK)))
      {
      if ((mask & item) == item)
      {
      effectivePermissionList.Add(rightsmap[item.ToString()]);
      i++;
      }

      }
      }
      //Clear Memory
      {
      Marshal.FreeHGlobal(reply.GrantedAccessMask);
      if (reply.Error != IntPtr.Zero)
      Marshal.FreeHGlobal(reply.Error);
      if (UserSid != IntPtr.Zero)
      Marshal.FreeHGlobal(UserSid);
      if (pSidOwner != IntPtr.Zero)
      Marshal.Release(pSidOwner);
      if (pSidGroup != IntPtr.Zero)
      Marshal.Release(pSidGroup);
      if (pDacl != IntPtr.Zero)
      Marshal.Release(pDacl);
      if (pSacl != IntPtr.Zero)
      Marshal.Release(pSacl);
      if (pSecurityDescriptor != IntPtr.Zero)
      Marshal.Release(pSecurityDescriptor);
      if (reply.SaclEvaluationResults != IntPtr.Zero)
      Marshal.Release(reply.SaclEvaluationResults);
      if (request.OptionalArguments != IntPtr.Zero)
      Marshal.Release(request.OptionalArguments);

      if (AccessReply != IntPtr.Zero)
      AuthzFreeHandle(AccessReply);
      if (hManager != IntPtr.Zero)
      AuthzFreeResourceManager(hManager);
      if (pClientContext != IntPtr.Zero)
      AuthzFreeContext(pClientContext);
      AuthzFreeCentralAccessPolicyCache();
      }

      if (i == 16)
      {
      effectivePermissionList.Insert(0, "Full Control");
      return PermissionValues.FULL_CONTROL;
      }
      PermissionValues per = PermissionValues.NONE;
      foreach (string r in effectivePermissionList)
      {

      switch (r)
      {
      case "Traverse Folder / execute file":
      per |= PermissionValues.FILE_TRAVERSE;
      break;
      case "List folder / read data":
      per |= PermissionValues.FILE_LIST_DIRECTORY;
      break;
      case "Read attributes":
      per |= PermissionValues.FILE_READ_ATTRIBUTES;
      break;
      case "Read extended attributes":
      per |= PermissionValues.FILE_READ_EA;
      break;
      case "Create files / write files":
      per |= PermissionValues.FILE_ADD_FILE;
      break;
      case "Create files / write files":
      per |= PermissionValues.FILE_WRITE_DATA;
      break;
      case "Create folders / append data":
      per |= (PermissionValues.FILE_ADD_SUBDIRECTORY | PermissionValues.FILE_APPEND_DATA);
      break;
      case "Write attributes":
      per |= PermissionValues.FILE_WRITE_ATTRIBUTES;
      break;
      case "Write extended attributes":
      per |= PermissionValues.FILE_WRITE_EA;
      break;
      case "Delete subfolders and files":
      per |= PermissionValues.FILE_DELETE_CHILD;
      break;
      case "Delete":
      per |= PermissionValues.DELETE;
      break;
      case "Read permission":
      per |= PermissionValues.READ_CONTROL;
      break;
      case "Change permission":
      per |= PermissionValues.WRITE_DAC;
      break;
      case "Take ownership":
      per |= PermissionValues.WRITE_OWNER;
      break;
      }
      }

      //foreach(var obj in request.ObjectTypeList)
      //{

      //}
      return per;

      }

      return PermissionValues.NONE;

      }

      public void Dispose()
      {
      GC.SuppressFinalize(this);
      }
      }
      }









      share|improve this question
















      I have situation where I need to traverse filesystem and calculate effective permission of users on files and directories and for that I'm using code the shown below. The issue is this code is creating managed memory up to 2 GB in my case.



      I've tried every possible thing to fix the memory leak as shown in code but still un-managed memory is growing. Please help me with the code below. I tried to dispose the object and also by using authz memory release methods but nothing works for me.



      using System;
      using System.Collections.Generic;
      using System.Runtime.InteropServices;
      using System.Security.Principal;

      namespace EffectiveRightsUsingAuthzAPI
      {
      public class Helper:IDisposable
      {
      [DllImport("advapi32.dll", SetLastError = true)]
      static extern uint GetEffectiveRightsFromAcl(IntPtr pDacl, ref TRUSTEE pTrustee, ref ACCESS_MASK pAccessRights);

      [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 4)]
      struct TRUSTEE
      {
      IntPtr pMultipleTrustee; // must be null
      public int MultipleTrusteeOperation;
      public TRUSTEE_FORM TrusteeForm;
      public TRUSTEE_TYPE TrusteeType;
      [MarshalAs(UnmanagedType.LPStr)]
      public string ptstrName;
      }
      [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 4)]
      public struct LUID
      {
      public uint LowPart;
      public int HighPart;
      }

      [StructLayout(LayoutKind.Sequential)]
      public struct AUTHZ_ACCESS_REQUEST
      {
      public int DesiredAccess;
      public byte PrincipalSelfSid;
      public OBJECT_TYPE_LIST ObjectTypeList;
      public int ObjectTypeListLength;
      public IntPtr OptionalArguments;
      };
      [StructLayout(LayoutKind.Sequential)]
      public struct OBJECT_TYPE_LIST
      {
      OBJECT_TYPE_LEVEL Level;
      int Sbz;
      IntPtr ObjectType;
      };

      [StructLayout(LayoutKind.Sequential)]
      public struct AUTHZ_ACCESS_REPLY
      {
      public int ResultListLength;
      public IntPtr GrantedAccessMask;
      public IntPtr SaclEvaluationResults;
      public IntPtr Error;
      };

      public enum OBJECT_TYPE_LEVEL : int
      {
      ACCESS_OBJECT_GUID = 0,
      ACCESS_PROPERTY_SET_GUID = 1,
      ACCESS_PROPERTY_GUID = 2,
      ACCESS_MAX_LEVEL = 4
      };
      enum TRUSTEE_FORM
      {
      TRUSTEE_IS_SID,
      TRUSTEE_IS_NAME,
      TRUSTEE_BAD_FORM,
      TRUSTEE_IS_OBJECTS_AND_SID,
      TRUSTEE_IS_OBJECTS_AND_NAME
      }

      enum AUTHZ_RM_FLAG : uint
      {
      AUTHZ_RM_FLAG_NO_AUDIT = 1,
      AUTHZ_RM_FLAG_INITIALIZE_UNDER_IMPERSONATION = 2,
      AUTHZ_RM_FLAG_NO_CENTRAL_ACCESS_POLICIES = 4,
      }

      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
      }

      [DllImport("advapi32.dll", CharSet = CharSet.Auto)]
      static extern uint GetNamedSecurityInfo(
      string pObjectName,
      SE_OBJECT_TYPE ObjectType,
      SECURITY_INFORMATION SecurityInfo,
      out IntPtr pSidOwner,
      out IntPtr pSidGroup,
      out IntPtr pDacl,
      out IntPtr pSacl,
      out IntPtr pSecurityDescriptor);
      [DllImport("authz.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall, EntryPoint = "AuthzInitializeContextFromSid", CharSet = CharSet.Unicode)]
      static extern public bool AuthzInitializeContextFromSid(
      int Flags,
      IntPtr UserSid,
      IntPtr AuthzResourceManager,
      IntPtr pExpirationTime,
      LUID Identitifier,
      IntPtr DynamicGroupArgs,
      out IntPtr pAuthzClientContext
      );



      [DllImport("authz.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall, EntryPoint = "AuthzInitializeResourceManager", CharSet = CharSet.Unicode)]
      static extern public bool AuthzInitializeResourceManager(
      int flags,
      IntPtr pfnAccessCheck,
      IntPtr pfnComputeDynamicGroups,
      IntPtr pfnFreeDynamicGroups,
      string name,
      out IntPtr rm
      );
      [DllImport("authz.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall, EntryPoint = "AuthzFreeResourceManager", CharSet = CharSet.Unicode)]
      static extern public bool AuthzFreeResourceManager(IntPtr hManager);

      [DllImport("authz.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall, EntryPoint = "AuthzFreeHandle", CharSet = CharSet.Unicode)]
      static extern public bool AuthzFreeHandle(IntPtr hAccessCheckResults);

      [DllImport("authz.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall, EntryPoint = "AuthzFreeContext", CharSet = CharSet.Unicode)]
      static extern public bool AuthzFreeContext(IntPtr hAuthzClientContext);
      [DllImport("authz.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall, EntryPoint = "AuthzFreeCentralAccessPolicyCache", CharSet = CharSet.Unicode)]
      static extern public bool AuthzFreeCentralAccessPolicyCache();

      [DllImport("authz.dll", EntryPoint = "AuthzAccessCheck", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
      private static extern bool AuthzAccessCheck(int flags,
      IntPtr hAuthzClientContext,
      ref AUTHZ_ACCESS_REQUEST pRequest,
      IntPtr AuditEvent,
      IntPtr pSecurityDescriptor,
      byte OptionalSecurityDescriptorArray,
      int OptionalSecurityDescriptorCount,
      ref AUTHZ_ACCESS_REPLY pReply,
      out IntPtr phAccessCheckResults);

      enum ACCESS_MASK : uint
      {
      FILE_TRAVERSE = 0x20,
      FILE_LIST_DIRECTORY = 0x1,
      FILE_READ_DATA = 0x1,
      FILE_READ_ATTRIBUTES = 0x80,
      FILE_READ_EA = 0x8,
      FILE_ADD_FILE = 0x2,
      FILE_WRITE_DATA = 0x2,
      FILE_ADD_SUBDIRECTORY = 0x4,
      FILE_APPEND_DATA = 0x4,
      FILE_WRITE_ATTRIBUTES = 0x100,
      FILE_WRITE_EA = 0x10,
      FILE_DELETE_CHILD = 0x40,
      DELETE = 0x10000,
      READ_CONTROL = 0x20000,
      WRITE_DAC = 0x40000,
      WRITE_OWNER = 0x80000,


      ////////FILE_EXECUTE =0x20,
      }

      [Flags]
      enum SECURITY_INFORMATION : uint
      {
      OWNER_SECURITY_INFORMATION = 0x00000001,
      GROUP_SECURITY_INFORMATION = 0x00000002,
      DACL_SECURITY_INFORMATION = 0x00000004,
      SACL_SECURITY_INFORMATION = 0x00000008,
      UNPROTECTED_SACL_SECURITY_INFORMATION = 0x10000000,
      UNPROTECTED_DACL_SECURITY_INFORMATION = 0x20000000,
      PROTECTED_SACL_SECURITY_INFORMATION = 0x40000000,
      PROTECTED_DACL_SECURITY_INFORMATION = 0x80000000
      }

      enum SE_OBJECT_TYPE
      {
      SE_UNKNOWN_OBJECT_TYPE = 0,
      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 PermissionValues GetEffectivePermissions(string UserName, string Path, out string object_sid)
      {
      List<string> result = new List<string>();
      IntPtr pSidOwner, pSidGroup, pDacl, pSacl, pSecurityDescriptor;
      ACCESS_MASK mask = new ACCESS_MASK();
      uint ret = GetNamedSecurityInfo(Path,
      SE_OBJECT_TYPE.SE_FILE_OBJECT,
      SECURITY_INFORMATION.DACL_SECURITY_INFORMATION | SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION | SECURITY_INFORMATION.GROUP_SECURITY_INFORMATION,
      out pSidOwner, out pSidGroup, out pDacl, out pSacl, out pSecurityDescriptor);

      IntPtr hManager = IntPtr.Zero;

      bool f = AuthzInitializeResourceManager(1, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, null, out hManager);

      NTAccount ac = new NTAccount(UserName);
      SecurityIdentifier sid;
      if (Imanami.PermissionProvider.FileSystem.Helper.isObjectSID(UserName))
      sid = new SecurityIdentifier(UserName);
      else
      sid = (SecurityIdentifier)ac.Translate(typeof(SecurityIdentifier));
      object_sid = sid.Value;
      byte bytes = new byte[sid.BinaryLength];
      sid.GetBinaryForm(bytes, 0);
      String _psUserSid = "";
      foreach (byte si in bytes)
      {
      _psUserSid += si;
      }

      LUID unusedSid = new LUID();
      IntPtr UserSid = Marshal.AllocHGlobal(bytes.Length);
      Marshal.Copy(bytes, 0, UserSid, bytes.Length);
      IntPtr pClientContext = IntPtr.Zero;

      if (f)
      {
      f = AuthzInitializeContextFromSid(0, UserSid, hManager, IntPtr.Zero, unusedSid, IntPtr.Zero, out pClientContext);


      AUTHZ_ACCESS_REQUEST request = new AUTHZ_ACCESS_REQUEST();
      request.DesiredAccess = 0x02000000;
      request.PrincipalSelfSid = null;
      request.ObjectTypeList = null;
      request.ObjectTypeListLength = 0;
      request.OptionalArguments = IntPtr.Zero;

      AUTHZ_ACCESS_REPLY reply = new AUTHZ_ACCESS_REPLY();
      reply.GrantedAccessMask = IntPtr.Zero;
      reply.ResultListLength = 0;
      reply.SaclEvaluationResults = IntPtr.Zero;
      IntPtr AccessReply = IntPtr.Zero;
      reply.Error = Marshal.AllocHGlobal(1020);
      reply.GrantedAccessMask = Marshal.AllocHGlobal(sizeof(uint));
      reply.ResultListLength = 1;
      int i = 0;
      Dictionary<String, String> rightsmap = new Dictionary<String, String>();
      List<string> effectivePermissionList = new List<string>();
      string rights = new string[14] { "Full Control", "Traverse Folder / execute file", "List folder / read data", "Read attributes", "Read extended attributes", "Create files / write files", "Create folders / append data", "Write attributes", "Write extended attributes", "Delete subfolders and files", "Delete", "Read permission", "Change permission", "Take ownership" };
      rightsmap.Add("FILE_TRAVERSE", "Traverse Folder / execute file");
      rightsmap.Add("FILE_LIST_DIRECTORY", "List folder / read data");
      rightsmap.Add("FILE_READ_DATA", "List folder / read data");
      rightsmap.Add("FILE_READ_ATTRIBUTES", "Read attributes");
      rightsmap.Add("FILE_READ_EA", "Read extended attributes");
      rightsmap.Add("FILE_ADD_FILE", "Create files / write files");
      rightsmap.Add("FILE_WRITE_DATA", "Create files / write files");
      rightsmap.Add("FILE_ADD_SUBDIRECTORY", "Create folders / append data");
      rightsmap.Add("FILE_APPEND_DATA", "Create folders / append data");
      rightsmap.Add("FILE_WRITE_ATTRIBUTES", "Write attributes");
      rightsmap.Add("FILE_WRITE_EA", "Write extended attributes");
      rightsmap.Add("FILE_DELETE_CHILD", "Delete subfolders and files");
      rightsmap.Add("DELETE", "Delete");
      rightsmap.Add("READ_CONTROL", "Read permission");
      rightsmap.Add("WRITE_DAC", "Change permission");
      rightsmap.Add("WRITE_OWNER", "Take ownership");


      f = AuthzAccessCheck(0, pClientContext, ref request, IntPtr.Zero, pSecurityDescriptor, null, 0, ref reply, out AccessReply);
      if (f)
      {
      int granted_access = Marshal.ReadInt32(reply.GrantedAccessMask);

      mask = (ACCESS_MASK)granted_access;

      foreach (ACCESS_MASK item in Enum.GetValues(typeof(ACCESS_MASK)))
      {
      if ((mask & item) == item)
      {
      effectivePermissionList.Add(rightsmap[item.ToString()]);
      i++;
      }

      }
      }
      //Clear Memory
      {
      Marshal.FreeHGlobal(reply.GrantedAccessMask);
      if (reply.Error != IntPtr.Zero)
      Marshal.FreeHGlobal(reply.Error);
      if (UserSid != IntPtr.Zero)
      Marshal.FreeHGlobal(UserSid);
      if (pSidOwner != IntPtr.Zero)
      Marshal.Release(pSidOwner);
      if (pSidGroup != IntPtr.Zero)
      Marshal.Release(pSidGroup);
      if (pDacl != IntPtr.Zero)
      Marshal.Release(pDacl);
      if (pSacl != IntPtr.Zero)
      Marshal.Release(pSacl);
      if (pSecurityDescriptor != IntPtr.Zero)
      Marshal.Release(pSecurityDescriptor);
      if (reply.SaclEvaluationResults != IntPtr.Zero)
      Marshal.Release(reply.SaclEvaluationResults);
      if (request.OptionalArguments != IntPtr.Zero)
      Marshal.Release(request.OptionalArguments);

      if (AccessReply != IntPtr.Zero)
      AuthzFreeHandle(AccessReply);
      if (hManager != IntPtr.Zero)
      AuthzFreeResourceManager(hManager);
      if (pClientContext != IntPtr.Zero)
      AuthzFreeContext(pClientContext);
      AuthzFreeCentralAccessPolicyCache();
      }

      if (i == 16)
      {
      effectivePermissionList.Insert(0, "Full Control");
      return PermissionValues.FULL_CONTROL;
      }
      PermissionValues per = PermissionValues.NONE;
      foreach (string r in effectivePermissionList)
      {

      switch (r)
      {
      case "Traverse Folder / execute file":
      per |= PermissionValues.FILE_TRAVERSE;
      break;
      case "List folder / read data":
      per |= PermissionValues.FILE_LIST_DIRECTORY;
      break;
      case "Read attributes":
      per |= PermissionValues.FILE_READ_ATTRIBUTES;
      break;
      case "Read extended attributes":
      per |= PermissionValues.FILE_READ_EA;
      break;
      case "Create files / write files":
      per |= PermissionValues.FILE_ADD_FILE;
      break;
      case "Create files / write files":
      per |= PermissionValues.FILE_WRITE_DATA;
      break;
      case "Create folders / append data":
      per |= (PermissionValues.FILE_ADD_SUBDIRECTORY | PermissionValues.FILE_APPEND_DATA);
      break;
      case "Write attributes":
      per |= PermissionValues.FILE_WRITE_ATTRIBUTES;
      break;
      case "Write extended attributes":
      per |= PermissionValues.FILE_WRITE_EA;
      break;
      case "Delete subfolders and files":
      per |= PermissionValues.FILE_DELETE_CHILD;
      break;
      case "Delete":
      per |= PermissionValues.DELETE;
      break;
      case "Read permission":
      per |= PermissionValues.READ_CONTROL;
      break;
      case "Change permission":
      per |= PermissionValues.WRITE_DAC;
      break;
      case "Take ownership":
      per |= PermissionValues.WRITE_OWNER;
      break;
      }
      }

      //foreach(var obj in request.ObjectTypeList)
      //{

      //}
      return per;

      }

      return PermissionValues.NONE;

      }

      public void Dispose()
      {
      GC.SuppressFinalize(this);
      }
      }
      }






      c# dllimport authz






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Jan 2 at 22:13









      marc_s

      583k13011241270




      583k13011241270










      asked Jan 2 at 20:26









      Ahmad BukhariAhmad Bukhari

      12




      12
























          0






          active

          oldest

          votes












          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54012707%2funmanaged-memory-issue-causing-by-authz-dll%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          0






          active

          oldest

          votes








          0






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes
















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54012707%2funmanaged-memory-issue-causing-by-authz-dll%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          MongoDB - Not Authorized To Execute Command

          How to fix TextFormField cause rebuild widget in Flutter

          in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith