Using C code to dynamically set file authority

  • 2021-11-14 06:46:37
  • OfStack

In development, we often use IO operations, such as creating and deleting files. There are many such requirements in the project, and we often code these operations, but set the permissions of files, which may be manually operated. Now introduce one kind of operation that uses code to dynamically set the permissions of files.

In setting permissions on files in DOtNet, the FileSystemAccessRule class will be used to operate the permissions of files.

1. Now look at the implementation code of FileSystemAccessRule under 1:


 public FileSystemAccessRule(
   IdentityReference identity,
   FileSystemRights fileSystemRights,
   AccessControlType type )
   : this(
    identity,
    AccessMaskFromRights( fileSystemRights, type ),
    false,
    InheritanceFlags.None,
    PropagationFlags.None,
    type )
  {
  }
  public FileSystemAccessRule(
   String identity,
   FileSystemRights fileSystemRights,
   AccessControlType type )
   : this(
    new NTAccount(identity),
    AccessMaskFromRights( fileSystemRights, type ),
    false,
    InheritanceFlags.None,
    PropagationFlags.None,
    type )
  {
  }
  //
  // Constructor for creating access rules for folder objects
  //
  public FileSystemAccessRule(
   IdentityReference identity,
   FileSystemRights fileSystemRights,
   InheritanceFlags inheritanceFlags,
   PropagationFlags propagationFlags,
   AccessControlType type )
   : this(
    identity,
    AccessMaskFromRights( fileSystemRights, type ),
    false,
    inheritanceFlags,
    propagationFlags,
    type )
  {
  }
  public FileSystemAccessRule(
   String identity,
   FileSystemRights fileSystemRights,
   InheritanceFlags inheritanceFlags,
   PropagationFlags propagationFlags,
   AccessControlType type )
   : this(
    new NTAccount(identity),
    AccessMaskFromRights( fileSystemRights, type ),
    false,
    inheritanceFlags,
    propagationFlags,
    type )
  {
  }
  internal FileSystemAccessRule(
   IdentityReference identity,
   int accessMask,
   bool isInherited,
   InheritanceFlags inheritanceFlags,
   PropagationFlags propagationFlags,
   AccessControlType type )
   : base(
    identity,
    accessMask,
    isInherited,
    inheritanceFlags,
    propagationFlags,
    type )
  {
  }
  #endregion
  #region Public properties
  public FileSystemRights FileSystemRights
  {
   get { return RightsFromAccessMask( base.AccessMask ); }
  }
  internal static int AccessMaskFromRights( FileSystemRights fileSystemRights, AccessControlType controlType )
  {
   if (fileSystemRights < (FileSystemRights) 0 || fileSystemRights > FileSystemRights.FullControl)
    throw new ArgumentOutOfRangeException("fileSystemRights", Environment.GetResourceString("Argument_InvalidEnumValue", fileSystemRights, "FileSystemRights"));
   Contract.EndContractBlock();

   if (controlType == AccessControlType.Allow) {
    fileSystemRights |= FileSystemRights.Synchronize;
   }
   else if (controlType == AccessControlType.Deny) {
    if (fileSystemRights != FileSystemRights.FullControl &&
     fileSystemRights != (FileSystemRights.FullControl & ~FileSystemRights.DeleteSubdirectoriesAndFiles))
     fileSystemRights &= ~FileSystemRights.Synchronize;
   }
   return ( int )fileSystemRights;
  }
  internal static FileSystemRights RightsFromAccessMask( int accessMask )
  {
   return ( FileSystemRights )accessMask;
  }
 }

2. Since FileSystemAccessRule inherits from AccessRule, now look at the source code of AccessRule under 1:


/// <summary>
 ///  Represents a combination of the user's identity, access mask, and access control type (allowed or denied). <see cref="T:System.Security.AccessControl.AccessRule"/>  Object also contains information about how child objects inherit rules and how inheritance is propagated. 
 /// </summary>
 public abstract class AccessRule : AuthorizationRule
 {
 /// <summary>
 ///  Class with the specified value  <see cref="T:System.Security.AccessControl.AccessRule"/>  Class 1 New instances. 
 /// </summary>
 /// <param name="identity"> The identity of the access rule applied. This parameter must be a parameter that can be cast to  <see cref="T:System.Security.Principal.SecurityIdentifier"/>  Object of. </param><param name="accessMask"> The access mask for this rule. The access mask is 1 A  32  Bits, the meaning of which is defined by each integrator. </param><param name="isInherited"> If this rule inherits from the parent container; Otherwise,  true . </param><param name="inheritanceFlags"> Access the inheritance properties of the rule. </param><param name="propagationFlags"> Whether inherited access rules are automatically propagated. If  <paramref name="inheritanceFlags"/>  Set to  <see cref="F:System.Security.AccessControl.InheritanceFlags.None"/> The propagation flag is ignored. </param><param name="type"> Valid access control types. </param><exception cref="T:System.ArgumentException"><paramref name="identity"/>  Parameter cannot be cast to  <see cref="T:System.Security.Principal.SecurityIdentifier"/> , or  <paramref name="type"/>  Parameter contains an invalid value. </exception><exception cref="T:System.ArgumentOutOfRangeException"><paramref name="accessMask"/>  Parameter is zero, or  <paramref name="inheritanceFlags"/>  Or  <paramref name="propagationFlags"/>  Parameter contains an unrecognized flag value. </exception>
 protected AccessRule(IdentityReference identity, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type);
 /// <summary>
 ///  Gets the same as this  <see cref="T:System.Security.AccessControl.AccessRule"/>  Object associated with the  <see cref="T:System.Security.AccessControl.AccessControlType"/>  Object. 
 /// </summary>
 /// 
 /// <returns>
 ///  With this  <see cref="T:System.Security.AccessControl.AccessRule"/>  Object associated with the  <see cref="T:System.Security.AccessControl.AccessControlType"/>  Object. 
 /// </returns>
 public AccessControlType AccessControlType { get; }
 }

It seems that DotNet implementation of the file permissions set the operation of the class, now provide several specific file settings operation code:

3. Get a list of directory permissions:


 /// <summary>
  ///  Get a list of directory permissions 
  /// </summary>
  /// <param name="path"> The path to the directory. </param>
  /// <returns> Indicates the permissions list of the directory </returns>
  public IList<FileSystemRights> GetDirectoryPermission(string path)
  {
   try
   {
    if (!DirectoryExists(path))
     return null;
    IList<FileSystemRights> result = new List<FileSystemRights>();
    var dSecurity = Directory.GetAccessControl(new DirectoryInfo(path).FullName);
    foreach (FileSystemAccessRule rule in dSecurity.GetAccessRules(true, true, typeof(NTAccount)))
     result.Add(rule.FileSystemRights);
    return result;
   }
   catch (Exception e)
   {
    throw new Exception(e.Message, e);
   }
  }

4. Set directory permissions


 /// <summary>
  /// Set directory permissions 
  /// </summary>
  /// <param name="path"> The path to the directory. </param>
  /// <param name="permission"> The permissions set on the directory. </param>
  /// <returns> A value indicating whether permissions are applied to the directory. </returns>
  public bool SetDirectoryPermission(string path, FileSystemRights permission)
  {
   try
   {
    if (!DirectoryExists(path))
     return false;
    var accessRule = new FileSystemAccessRule("Users", permission,
           InheritanceFlags.None,
           PropagationFlags.NoPropagateInherit,
           AccessControlType.Allow);

    var info = new DirectoryInfo(path);
    var security = info.GetAccessControl(AccessControlSections.Access);
    bool result;
    security.ModifyAccessRule(AccessControlModification.Set, accessRule, out result);
    if (!result)
     return false;
    const InheritanceFlags iFlags = InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit;
    accessRule = new FileSystemAccessRule("Users", permission,
           iFlags,
           PropagationFlags.InheritOnly,
           AccessControlType.Allow);

    security.ModifyAccessRule(AccessControlModification.Add, accessRule, out result);
    if (!result)
     return false;
    info.SetAccessControl(security);
    return true;
   }
   catch (Exception e)
   {
    throw new Exception(e.Message, e);
   }
  }

5. Set up directory permission list


 /// <summary>
  ///  Setting the Directory Permission List 
  /// </summary>
  /// <param name="path"> The path to the directory. </param>
  /// <param name="permissions"> The permissions set on the directory. </param>
  /// <returns> A value indicating whether permissions are applied to the directory. </returns>
  public bool SetDirectoryPermissions(string path, FileSystemRights[] permissions)
  {
   try
   {
    if (!DirectoryExists(path) || permissions == null || !permissions.Any())
     return false;
    foreach (var permission in permissions)
     if (!SetDirectoryPermission(path, permission))
      return false;
     return true;
   }
   catch (Exception e)
   {
    throw new Exception(e.Message, e);
   }
  }

The above is a brief introduction to the file permission setting operation.


Related articles: