Unmanaged memory issue causing by Authz.dll
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
add a comment |
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
add a comment |
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
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
c# dllimport authz
edited Jan 2 at 22:13
marc_s
583k13011241270
583k13011241270
asked Jan 2 at 20:26
Ahmad BukhariAhmad Bukhari
12
12
add a comment |
add a comment |
0
active
oldest
votes
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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