2008-12-12 3 views
4

Je tente de vérifier les droits sur un fichier particulier pour un fiduciaire spécifique et j'utilise l'API Win32 GetEffectiveRightsFromAcl(). Lorsque le fichier est accessible par un groupe de domaine, la fonction renvoie 5 (Accès refusé) lorsqu'un compte local (admin ou autre) est utilisé pour exécuter la fonction.Obtenir l'accès refusé avec GetEffectiveRightsFromAcl() ..?

Ces trois déclarations résument le comportement que je vois avec GetEffectiveRightsFromAcl():

  • Lorsque le groupe de domaine a des droits sur le fichier et le programme fonctionne sous un compte local: Accès refusé.
  • Lorsque le groupe de domaine a des droits sur le fichier et le programme fonctionne sous un compte de domaine ou système local: Succès
  • Lorsque le groupe de domaine ne dispose pas de droits au dossier et le programme fonctionne sous un compte: Succès

Est-ce que quelqu'un sait la raison derrière cela? Il me semble que c'est lié à la sécurité Active Directory. Quels paramètres pourraient affecter ce et ce qui serait un bon moyen de déboguer cela?

En outre, j'ai entendu que GetEffectiveRightsFromAcl() peut être généralement problématique et utiliser AccessCheck() à la place. Cependant je dois pouvoir prendre un SID arbitraire et vérifier son accès contre un fichier et puisque AccessCheck() exige un jeton d'usurpation je ne sais pas comment je pourrais greate un jeton d'un SID arbitraire ... Des idées? Merci

Bob

Répondre

2
  • si le groupe de domaine ont droit au fichier , cette fonction doit accéder le répertoire actif pour énumérer les membres du groupe du fiduciaire (au moins si elle est un utilisateur de domaine). Si votre programme s'exécute sous le compte local , alors ce compte n'a pas le droit d'accéder au répertoire actif , d'où le code retour .
  • compte de domaine et le système local ont accès au répertoire actif. Le système local est le compte d'ordinateur dans le répertoire actif (les ordinateurs sont des utilisateurs similaires dans AD).
  • Si aucun groupe de domaine n'a accès au fichier , la fonction ne doit pas vérifier avec le répertoire actif. Donc, les utilisateurs locaux réussissent aussi.
3

J'ai en C# utilisé et cela fonctionne bien pour moi.

using System; 
using System.Runtime.InteropServices; 
using System.Security.Principal; 
using System.Security.AccessControl; 

namespace DACL 
{ 
    class Class1 
    { 
     private enum MULTIPLE_TRUSTEE_OPERATION 
     { 
      NO_MULTIPLE_TRUSTEE, 
      TRUSTEE_IS_IMPERSONATE 
     } 

     private enum TRUSTEE_FORM 
     { 
      TRUSTEE_IS_SID, 
      TRUSTEE_IS_NAME, 
      TRUSTEE_BAD_FORM, 
      TRUSTEE_IS_OBJECTS_AND_SID, 
      TRUSTEE_IS_OBJECTS_AND_NAME 
     } 

     private 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 
     } 

     private struct TRUSTEE 
     { 
      public IntPtr pMultipleTrustee; 
      public MULTIPLE_TRUSTEE_OPERATION MultipleTrusteeOperation; 
      public TRUSTEE_FORM TrusteeForm; 
      public TRUSTEE_TYPE TrusteeType; 
      public IntPtr ptstrName; 
     } 

     [DllImport("advapi32.dll", SetLastError = true)] 
     private static extern void BuildTrusteeWithSid(
      ref TRUSTEE pTrustee, 
      byte[] sid 
     ); 

     [DllImport("advapi32.dll")] 
     private static extern uint GetEffectiveRightsFromAcl(byte[] pacl, ref TRUSTEE pTrustee, ref uint pAccessRights); 

     public bool HasAccess(SecurityIdentifier sid) 
     { 
      DiscretionaryAcl dacl = <DACL from somewhere>; 

      byte[] daclBuffer = new byte[dacl.BinaryLength]; 
      dacl.GetBinaryForm(daclBuffer, 0); 

      byte[] sidBuffer = new byte[sid.BinaryLength]; 
      sid.GetBinaryForm(sidBuffer, 0); 

      TRUSTEE t = new TRUSTEE(); 
      BuildTrusteeWithSid(ref t, sidBuffer); 

      uint access = 0; 
      uint hr = GetEffectiveRightsFromAcl(daclBuffer, ref t, ref access); 

      int i = Marshal.Release(t.ptstrName); 

      return ((access & <Desired Access>) == <Desired Access>) ? true : false; 
     } 
    } 
} 
Questions connexes