2011-10-13 9 views
2

AuthzAccessCheck의 PInvoke를 사용하여 C# 응용 프로그램에서 작동하고 오류 코드 87 : invalid parameter를 계속 실행하려고합니다. 초기 테스트에서 나는 예제 코드에서 GetAccess 루틴의 기본 구조를 따르려고 시도 했었습니다. here을 찾았습니다.PInvoke AuthzAccessCheck에서 C#으로 오류 87 : 유효하지 않은 매개 변수

나는이 작업을하기 위해 내가 생각할 수있는 모든 변형을 시도했으며,이 시점에서 나는 꽤 꼼짝 못한다. 누구든지 내가 뭘 잘못하고 있는지 설명하는 데 도움이 될 수 있습니까?

이 여기에 전체 테스트 코드입니다 :

using System; 
using System.Collections.Generic; 
using System.Runtime.InteropServices; 
using System.Security.Principal; 
using System.Security.AccessControl; 
using System.ComponentModel; 
using System.Text; 

namespace PinvokeTest 
{ 
    class Program 
    { 
     public interface IFunctionResult 
     { 
      bool Error { get; } 
      string Message { get; } 
     } 

     public class FunctionResult : IFunctionResult 
     { 
      public FunctionResult() { _err = false; _msg = string.Empty; } 
      public FunctionResult(string message) { _err = true; _msg = message; } 

      private bool _err; 
      private string _msg; 

      public bool Error { get { return _err; } } 
      public string Message { get { return _msg; } } 
     } 

     static void Main(string[] args) 
     { 
      string file_name = "C:\\AUTOEXEC.BAT"; 

      System.IO.FileInfo fi = new System.IO.FileInfo(file_name); 
      FileSecurity fs = fi.GetAccessControl(); 
      byte[] rsd_bytes = fs.GetSecurityDescriptorBinaryForm(); 

      SecurityIdentifier user_sid; 
      using (WindowsIdentity current_user = WindowsIdentity.GetCurrent()) { user_sid = current_user.User; } 
      byte[] sid_bytes = new byte[user_sid.BinaryLength]; 
      user_sid.GetBinaryForm(sid_bytes, 0); 

      IFunctionResult res = TestAuthzAccessCheck(rsd_bytes, sid_bytes); 
      if (res.Error) { Console.WriteLine(res.Message); } 
      else { Console.WriteLine("SUCCESS"); } 
     } 

     // see : http://msdn.microsoft.com/en-us/library/aa446637%28VS.85%29.aspx 
     public static IFunctionResult TestAuthzAccessCheck(byte[] rsd_bytes, byte[] sid_bytes) 
     { 
      FunctionResult ret = null; 

      IntPtr hClientContext = IntPtr.Zero; 
      IntPtr hResourceManager = IntPtr.Zero; 
      IntPtr reply_ptr = IntPtr.Zero; 
      IntPtr request_ptr = IntPtr.Zero; 
      IntPtr check_results = IntPtr.Zero; 

      LUID unused_id = new LUID(); 

      AUTHZ_ACCESS_REPLY reply = new AUTHZ_ACCESS_REPLY(); 
      reply.Error = IntPtr.Zero; 
      reply.GrantedAccessMask = IntPtr.Zero; 
      reply.ResultListLength = 0; 
      reply.SaclEvaluationResults = IntPtr.Zero; 

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

      try 
      { 
       for (int x = 0; x == 0; x++) 
       { 
        if (!AuthzInitializeResourceManager((int)AuthzResourceManagerFlags.NO_AUDIT, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, "", out hResourceManager)) 
        { 
         int err = Marshal.GetLastWin32Error(); 
         Win32Exception win32Exception = new Win32Exception(err); 
         ret = new FunctionResult("AuthzInitializeResourceManager Error[" + err + "] : " + win32Exception.Message); 
         break; 
        } 

        if (!AuthzInitializeContextFromSid((int)AuthzContextFlags.NONE, sid_bytes, hResourceManager, IntPtr.Zero, unused_id, IntPtr.Zero, out hClientContext)) 
        { 
         int err = Marshal.GetLastWin32Error(); 
         Win32Exception win32Exception = new Win32Exception(err); 
         ret = new FunctionResult("AuthzInitializeContextFromSid Error[" + err + "] : " + win32Exception.Message); 
         break; 
        } 

        reply.Error = Marshal.AllocHGlobal(1020); 
        reply.GrantedAccessMask = Marshal.AllocHGlobal(sizeof(uint)); 
        reply.ResultListLength = 1; 

        request_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(request)); 
        Marshal.StructureToPtr(request, request_ptr, false); 

        reply_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(reply)); 
        Marshal.StructureToPtr(reply, reply_ptr, false); 

        if (!AuthzAccessCheck((int)AuthzAccessCheckFlags.NONE, hClientContext, request_ptr, IntPtr.Zero, rsd_bytes, null, 0, ref reply_ptr, out check_results)) 
        { 
         int err = Marshal.GetLastWin32Error(); 
         Win32Exception win32Exception = new Win32Exception(err); 
         ret = new FunctionResult("AuthzAccessCheck Error[" + err + "] : " + win32Exception.Message); 
         break; 
        } 
       } 
      } 
      catch (Exception e) 
      { 
       ret = new FunctionResult("TestAuthzAccessCheck Exception : " + e.Message); 
      } 
      finally 
      { 
       if (reply.GrantedAccessMask != IntPtr.Zero) { Marshal.FreeHGlobal(reply.GrantedAccessMask); } 
       if (reply.Error != IntPtr.Zero) { Marshal.FreeHGlobal(reply.Error); } 
       if (reply_ptr != IntPtr.Zero) { Marshal.FreeHGlobal(reply_ptr); } 
       if (request_ptr != IntPtr.Zero) { Marshal.FreeHGlobal(request_ptr); } 
       if (hClientContext != IntPtr.Zero) 
       { 
        if (!AuthzFreeContext(hClientContext)) 
        { 
         int err = Marshal.GetLastWin32Error(); 
         Win32Exception win32Exception = new Win32Exception(err); 
         ret = new FunctionResult((ret == null ? "" : (ret.Message + " ")) + "AuthzFreeContext Error[" + err + "] : " + win32Exception.Message); 
        } 
       } 
       if (hResourceManager != IntPtr.Zero) 
       { 
        if (!AuthzFreeResourceManager(hResourceManager)) 
        { 
         int err = Marshal.GetLastWin32Error(); 
         Win32Exception win32Exception = new Win32Exception(err); 
         ret = new FunctionResult((ret == null ? "" : (ret.Message + " ")) + "AuthzFreeResourceManager Error[" + err + "] : " + win32Exception.Message); 
        } 
       } 
      } 

      return ret; 
     } 


     public const int MAXIMUM_ALLOWED = 0x02000000; 

     [Flags] 
     public enum AuthzResourceManagerFlags : int 
     { 
      NONE = 0, 
      NO_AUDIT = 0x1, 
      INITIALIZE_UNDER_IMPERSONATION = 0x2, 
      VALID_INIT_FLAGS = (NO_AUDIT | INITIALIZE_UNDER_IMPERSONATION), 
     }; 

     [Flags] 
     public enum AuthzContextFlags : int 
     { 
      NONE = 0, 
      SKIP_TOKEN_GROUPS = 0x2, 
      REQUIRE_S4U_LOGON = 0x4, 
      COMPUTE_PRIVILEGES = 0x8 
     }; 

     [Flags] 
     public enum AuthzAccessCheckFlags : int 
     { 
      NONE = 0, 
      NO_DEEP_COPY_SD = 0x00000001 
     }; 

     [Flags] 
     public enum AuthzGenerateFlags : int 
     { 
      NONE = 0, 
      SUCCESS_AUDIT = 0x00000001, 
      FAILURE_AUDIT = 0x00000002, 
     }; 

     public enum OBJECT_TYPE_LEVEL : int 
     { 
      ACCESS_OBJECT_GUID = 0, 
      ACCESS_PROPERTY_SET_GUID = 1, 
      ACCESS_PROPERTY_GUID = 2, 
      ACCESS_MAX_LEVEL = 4 
     }; 

     [StructLayout(LayoutKind.Sequential)] 
     public struct LUID 
     { 
      public uint LowPart; 
      public int HighPart; 
     }; 

     [StructLayout(LayoutKind.Sequential)] 
     public struct OBJECT_TYPE_LIST 
     { 
      OBJECT_TYPE_LEVEL Level; 
      int Sbz; 
      IntPtr ObjectType; 
     }; 

     [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 AUTHZ_ACCESS_REPLY 
     { 
      public int ResultListLength; 
      public IntPtr GrantedAccessMask; 
      public IntPtr SaclEvaluationResults; 
      public IntPtr Error; 
     }; 

     /* 
     * __in  DWORD flags, 
     * __in  AUHZ_CLIENT_CONTEXT_HANDLE hAuthzClientContext, 
     * __in  PAUTHZ_ACCESS_REQUEST pRequest, 
     * __in_opt AUTHZ_AUDIT_EVENT_HANDLE AuditEvent, 
     * __in  PSECURITY_DESCRIPTOR pSecurityDescriptor, 
     * __in_opt PSECURITY_DESCRIPTOR *OptionalSecurityDescriptorArray, 
     * __in_opt DWORD OptionalSecurityDescriptorCount, 
     * __inout PAUTHZ_ACCESS_REPLY pReply, 
     * __out_opt PAUTHZ_ACCESS_CHECK_RESULTS_HANDLE phAccessCheckResults 
     */ 
     [DllImport("authz.dll", EntryPoint = "AuthzAccessCheck", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)] 
     private static extern bool AuthzAccessCheck(int flags, IntPtr hAuthzClientContext, 
      IntPtr pRequest, IntPtr AuditEvent, 
      [MarshalAs(UnmanagedType.LPArray)] byte[] pSecurityDescriptor, [MarshalAs(UnmanagedType.LPArray)] byte[] OptionalSecurityDescriptorArray, 
      int OptionalSecurityDescriptorCount, ref IntPtr pReply, out IntPtr phAccessCheckResults); 


     /* 
     * BOOL WINAPI AuthzInitializeResourceManager(
     * __in  DWORD flags, 
     * __in_opt PFN_AUTHZ_DYNAMIC_ACCESS_CHECK pfnAccessCheck, 
     * __in_opt PFN_AUTHZ_COMPUTE_DYNAMIC_GROUPS pfnComputeDynamicGroups, 
     * __in_opt PFN_AUTHZ_FREE_DYNAMIC_GROUPS pfnFreeDynamicGroups, 
     * __in  PCWSTR szResourceManagerName, 
     * __out  PAUTHZ_RESOURCE_MANAGER_HANDLE phAuthzResourceManager 
     */ 
     [DllImport("authz.dll", EntryPoint = "AuthzInitializeResourceManager", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)] 
     private static extern bool AuthzInitializeResourceManager(int flags, IntPtr pfnAccessCheck, IntPtr pfnComputeDynamicGroups, 
      IntPtr pfnFreeDynamicGroups, string szResourceManagerName, out IntPtr phAuthzResourceManager); 


     /* 
     * BOOL WINAPI AuthzInitializeContextFromSid(
     * __in  DWORD Flags, 
     * __in  PSID UserSid, 
     * __in_opt AUTHZ_RESOURCE_MANAGER_HANDLE hAuthzResourceManager, 
     * __in  PLARGE_INTEGER pExpirationTime, 
     * __in  LUID Identifier, 
     * __in_opt PVOID DynamicGroupArgs, 
     * __out  PAUTHZ_CLIENT_CONTEXT_HANDLE pAuthzClientContext 
     */ 
     [DllImport("authz.dll", EntryPoint = "AuthzInitializeContextFromSid", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)] 
     private static extern bool AuthzInitializeContextFromSid(int flags, byte[] UserSid, IntPtr hAuthzResourceManager, IntPtr pExpirationTime, 
      LUID Identifier, IntPtr DynamicGroupArgs, out IntPtr pAuthzClientContext); 


     [DllImport("authz.dll", EntryPoint = "AuthzFreeContext", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)] 
     private static extern bool AuthzFreeContext(IntPtr hAuthzCLientContext); 


     [DllImport("authz.dll", EntryPoint = "AuthzFreeResourceManager", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)] 
     private static extern bool AuthzFreeResourceManager(IntPtr hAuthzResourceManager); 
    } 
} 

답변

2

내가 문제를 파악, 그것은 마샬링 문제였다 밝혀졌습니다. AuthzAccessCheck에 대한 올바른 서명

[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, 
    byte[] pSecurityDescriptor, byte[] OptionalSecurityDescriptorArray, 
    int OptionalSecurityDescriptorCount, ref AUTHZ_ACCESS_REPLY pReply, out IntPtr phAccessCheckResults); 

하고 그것을 사용하는 적절한 방법은 수동으로 구조를 마샬링하지 않는 것입니다. 나를 위해 일하는 스 니펫은 다음과 같습니다.

reply.Error = Marshal.AllocHGlobal(1020); 
reply.GrantedAccessMask = Marshal.AllocHGlobal(sizeof(uint)); 
reply.ResultListLength = 1; 

if (!AuthzAccessCheck((int)AuthzAccessCheckFlags.NONE, hClientContext, ref request, IntPtr.Zero, dacl_bytes, null, 0, ref reply, out check_results)) 
{ 
    int err = Marshal.GetLastWin32Error(); 
    ret = new FunctionResult<int>("AuthzAccessCheck Error[" + err + "] : " + ResultWin32.GetErrorName(err)); 
    break; 
} 
int granted_access = Marshal.ReadInt32(reply.GrantedAccessMask);