Example #1
0
 public void SetSecurity(FileSystemSecurity security, AccessControlSections sections)
 {
     lock (Lock) {
         if ((sections & AccessControlSections.Owner) != 0)
         {
             _directory.Owner = (SecurityIdentifier)security.GetOwner(typeof(SecurityIdentifier));
         }
         if ((sections & AccessControlSections.Group) != 0)
         {
             _directory.Group = (SecurityIdentifier)security.GetGroup(typeof(SecurityIdentifier));
         }
         if ((sections & AccessControlSections.Access) != 0)
         {
             _fileSystem.RemoveAccessRules(_directory);
             foreach (var r in security.GetAccessRules(true, false, typeof(SecurityIdentifier)))
             {
                 _fileSystem.AddAccessRule(_directory, (FileSystemAccessRule)r);
             }
         }
         if ((sections & AccessControlSections.Audit) != 0)
         {
             _fileSystem.RemoveAuditRules(_directory);
             foreach (var r in security.GetAuditRules(true, false, typeof(SecurityIdentifier)))
             {
                 _fileSystem.AddAuditRule(_directory, (FileSystemAuditRule)r);
             }
         }
     }
 }
        /// <summary>
        /// Sets the SecurityDescriptor at the specified path.
        /// </summary>
        /// <param name="path">
        /// The path of the item to set the security descriptor on.
        /// It may be a drive or provider-qualified path and may include.
        /// glob characters.
        /// </param>
        /// <param name="securityDescriptor">
        /// The new security descriptor for the item.
        /// </param>
        /// <exception cref="System.ArgumentException">
        ///     path is null or empty.
        /// </exception>
        /// <exception cref="System.ArgumentNullException">
        ///     securitydescriptor is null.
        /// </exception>
        public void SetSecurityDescriptor(
            string path,
            ObjectSecurity securityDescriptor)
        {
            if (string.IsNullOrEmpty(path))
            {
                throw PSTraceSource.NewArgumentException("path");
            }

            path = NormalizePath(path);

            if (securityDescriptor == null)
            {
                throw PSTraceSource.NewArgumentNullException("securityDescriptor");
            }

            if (!File.Exists(path) && !Directory.Exists(path))
            {
                ThrowTerminatingError(CreateErrorRecord(path,
                                                        "SetSecurityDescriptor_FileNotFound"));
            }

            FileSystemSecurity sd = securityDescriptor as FileSystemSecurity;

            if (sd == null)
            {
                throw PSTraceSource.NewArgumentException("securityDescriptor");
            }
            else
            {
                // This algorithm works around the following security descriptor complexities:
                //
                //     - In order to copy an ACL between files, you need to use the
                //       binary form, and transfer all sections. If you don't use the binary form,
                //       then the FileSystem only applies changes that have happened to that specific
                //       ACL object -- which will not be present if you are just stamping a specific
                //       ACL on a lot of files.
                //     - Copying a full ACL means copying its Audit section, which normal users
                //       don't have access to.
                //
                // In order to make this cmdlet support regular users modifying their own files,
                // the solution is to:
                //
                //     - First attempt to copy the entire security descriptor as we did in V1.
                //       This ensures backward compatability for administrator scripts that currently
                //       work.
                //     - If the attempt fails due to a PrivilegeNotHeld exception, try again with
                //       an estimate of the minimum required subset. This is an estimate, since the
                //       ACL object doesn't tell you exactly what's changed.
                //           - If their ACL doesn't include any audit rules, don't try to set the
                //             audit section. If it does contain Audit rules, continue to try and
                //             set the section, so they get an appropriate error message.
                //           - If their ACL has the same Owner / Group as the destination file,
                //             also don't try to set those sections.
                //       If they added audit rules, or made changes to the Owner / Group, they will
                //       still get an error message.
                //
                // We can't roll the two steps into one, as the second step can't handle the
                // situation where an admin wants to _clear_ the audit entries. It would be nice to
                // detect a difference in audit entries (like we do with Owner and Group,) but
                // retrieving the Audit entries requires SeSecurityPrivilege as well.

                try
                {
                    // Try to set the entire security descriptor
                    SetSecurityDescriptor(path, sd, AccessControlSections.All);
                }
                catch (PrivilegeNotHeldException)
                {
                    // Get the security descriptor of the destination path
                    ObjectSecurity existingDescriptor = new FileInfo(path).GetAccessControl();
                    Type           ntAccountType      = typeof(System.Security.Principal.NTAccount);

                    AccessControlSections sections = AccessControlSections.All;

                    // If they didn't modify any audit information, don't try to set
                    // the audit section.
                    int auditRuleCount = sd.GetAuditRules(true, true, ntAccountType).Count;
                    if ((auditRuleCount == 0) &&
                        (sd.AreAuditRulesProtected == existingDescriptor.AreAccessRulesProtected))
                    {
                        sections &= ~AccessControlSections.Audit;
                    }

                    // If they didn't modify the owner, don't try to set that section.
                    if (sd.GetOwner(ntAccountType) == existingDescriptor.GetOwner(ntAccountType))
                    {
                        sections &= ~AccessControlSections.Owner;
                    }

                    // If they didn't modify the group, don't try to set that section.
                    if (sd.GetGroup(ntAccountType) == existingDescriptor.GetGroup(ntAccountType))
                    {
                        sections &= ~AccessControlSections.Group;
                    }

                    // Try to set the security descriptor again, this time with a reduced set
                    // of sections.
                    SetSecurityDescriptor(path, sd, sections);
                }
            }
        }
Example #3
0
        public static void SetAccessControlExtracted([NotNull] this FileSystemSecurity security, [NotNull] String name)
        {
            if (security == null)
            {
                throw new ArgumentNullException(paramName: nameof(security));
            }

            name = name.ThrowIfBlank();

            var includeSections = AccessControlSections.Owner | AccessControlSections.Group;

            if (security.GetAccessRules(true, false, typeof(SecurityIdentifier)).Count > 0)
            {
                includeSections |= AccessControlSections.Access;
            }

            if (security.GetAuditRules(true, false, typeof(SecurityIdentifier)).Count > 0)
            {
                includeSections |= AccessControlSections.Audit;
            }

            UInt32             securityInfo = 0;
            SecurityIdentifier owner        = null;
            SecurityIdentifier group        = null;
            SystemAcl          sacl         = null;
            DiscretionaryAcl   dacl         = null;

            if ((includeSections & AccessControlSections.Owner) != AccessControlSections.None)
            {
                owner = security.GetOwner(typeof(SecurityIdentifier)) as SecurityIdentifier;

                if (owner != null)
                {
                    securityInfo |= ( UInt32 )SecurityInfos.Owner;
                }
            }

            if ((includeSections & AccessControlSections.Group) != AccessControlSections.None)
            {
                group = security.GetGroup(typeof(SecurityIdentifier)) as SecurityIdentifier;

                if (group != null)
                {
                    securityInfo |= ( UInt32 )SecurityInfos.Group;
                }
            }

            var securityDescriptorBinaryForm = security.GetSecurityDescriptorBinaryForm();

            var rawSecurityDescriptor     = new RawSecurityDescriptor(securityDescriptorBinaryForm, 0);
            var isDiscretionaryAclPresent = (rawSecurityDescriptor.ControlFlags & ControlFlags.DiscretionaryAclPresent) != ControlFlags.None;

            if ((includeSections & AccessControlSections.Audit) != AccessControlSections.None)
            {
                securityInfo |= ( UInt32 )SecurityInfos.SystemAcl;

                var isSystemAclPresent = (rawSecurityDescriptor.ControlFlags & ControlFlags.SystemAclPresent) != ControlFlags.None;

                if (isSystemAclPresent && rawSecurityDescriptor.SystemAcl != null && rawSecurityDescriptor.SystemAcl.Count > 0)
                {
                    // are all system acls on a file not a container?
                    const Boolean notAContainer          = false;
                    const Boolean notADirectoryObjectACL = false;

                    sacl = new SystemAcl(notAContainer, notADirectoryObjectACL, rawSecurityDescriptor.SystemAcl);
                }

                if ((rawSecurityDescriptor.ControlFlags & ControlFlags.SystemAclProtected) == ControlFlags.None)
                {
                    securityInfo |= UnprotectedSystemAcl;
                }
                else
                {
                    securityInfo |= ProtectedSystemAcl;
                }
            }

            if ((includeSections & AccessControlSections.Access) != AccessControlSections.None && isDiscretionaryAclPresent)
            {
                securityInfo |= ( UInt32 )SecurityInfos.DiscretionaryAcl;

                dacl = new DiscretionaryAcl(false, false, rawSecurityDescriptor.DiscretionaryAcl);

                securityInfo = (rawSecurityDescriptor.ControlFlags & ControlFlags.DiscretionaryAclProtected) == ControlFlags.None ?
                               securityInfo | UnprotectedDiscretionaryAcl :
                               securityInfo | ProtectedDiscretionaryAcl;
            }

            if (securityInfo == 0)
            {
                return;
            }

            var errorNum = SetSecurityInfo(ResourceType.FileObject, name, ( SecurityInfos )securityInfo, owner, group, sacl, dacl);   //eh?

            if (errorNum != 0)
            {
                var exception = GetExceptionFromWin32Error(errorNum, name);

                throw exception;
            }
        }
Example #4
0
        internal static void SetAccessControlExtracted(FileSystemSecurity security, string name)
        {
            //security.WriteLock();
            AccessControlSections includeSections = AccessControlSections.Owner | AccessControlSections.Group;

            if (security.GetAccessRules(true, false, typeof(SecurityIdentifier)).Count > 0)
            {
                includeSections |= AccessControlSections.Access;
            }
            if (security.GetAuditRules(true, false, typeof(SecurityIdentifier)).Count > 0)
            {
                includeSections |= AccessControlSections.Audit;
            }

            SecurityInfos      securityInfo = (SecurityInfos)0;
            SecurityIdentifier owner        = null;
            SecurityIdentifier group        = null;
            SystemAcl          sacl         = null;
            DiscretionaryAcl   dacl         = null;

            if ((includeSections & AccessControlSections.Owner) != AccessControlSections.None)
            {
                owner = (SecurityIdentifier)security.GetOwner(typeof(SecurityIdentifier));
                if (owner != null)
                {
                    securityInfo = securityInfo | SecurityInfos.Owner;
                }
            }

            if ((includeSections & AccessControlSections.Group) != AccessControlSections.None)
            {
                @group = (SecurityIdentifier)security.GetGroup(typeof(SecurityIdentifier));
                if (@group != null)
                {
                    securityInfo = securityInfo | SecurityInfos.Group;
                }
            }
            var securityDescriptorBinaryForm            = security.GetSecurityDescriptorBinaryForm();
            RawSecurityDescriptor rawSecurityDescriptor = null;
            bool isDiscretionaryAclPresent = false;

            if (securityDescriptorBinaryForm != null)
            {
                rawSecurityDescriptor     = new RawSecurityDescriptor(securityDescriptorBinaryForm, 0);
                isDiscretionaryAclPresent = (rawSecurityDescriptor.ControlFlags & ControlFlags.DiscretionaryAclPresent) != ControlFlags.None;
            }

            if ((includeSections & AccessControlSections.Audit) != AccessControlSections.None)
            {
                securityInfo = securityInfo | SecurityInfos.SystemAcl;
                sacl         = null;
                if (rawSecurityDescriptor != null)
                {
                    var isSystemAclPresent = (rawSecurityDescriptor.ControlFlags & ControlFlags.SystemAclPresent) != ControlFlags.None;
                    if (isSystemAclPresent && rawSecurityDescriptor.SystemAcl != null && rawSecurityDescriptor.SystemAcl.Count > 0)
                    {
                        // are all system acls on a file not a container?
                        const bool notAContainer          = false;
                        const bool notADirectoryObjectACL = false;

                        sacl = new SystemAcl(notAContainer, notADirectoryObjectACL,
                                             rawSecurityDescriptor.SystemAcl);
                    }
                    securityInfo = (SecurityInfos)(((rawSecurityDescriptor.ControlFlags & ControlFlags.SystemAclProtected) == ControlFlags.None ?
                                                    (uint)securityInfo | UnprotectedSystemAcl : (uint)securityInfo | ProtectedSystemAcl));
                }
            }
            if ((includeSections & AccessControlSections.Access) != AccessControlSections.None && isDiscretionaryAclPresent)
            {
                securityInfo = securityInfo | SecurityInfos.DiscretionaryAcl;
                dacl         = null;
                if (rawSecurityDescriptor != null)
                {
                    //if (!this._securityDescriptor.DiscretionaryAcl.EveryOneFullAccessForNullDacl)
                    {
                        dacl = new DiscretionaryAcl(false, false, rawSecurityDescriptor.DiscretionaryAcl);
                    }
                    securityInfo = (SecurityInfos)(((rawSecurityDescriptor.ControlFlags & ControlFlags.DiscretionaryAclProtected) == ControlFlags.None ?
                                                    (uint)securityInfo | UnprotectedDiscretionaryAcl : (uint)securityInfo | ProtectedDiscretionaryAcl));
                }
            }
            if (securityInfo == 0)
            {
                return;
            }

            int errorNum = SetSecurityInfo(ResourceType.FileObject, name, null, securityInfo, owner, @group, sacl, dacl);

            if (errorNum != 0)
            {
                Exception exception = GetExceptionFromWin32Error(errorNum, name);
                if (exception == null)
                {
                    if (errorNum == NativeMethods.ERROR_ACCESS_DENIED)
                    {
                        exception = new UnauthorizedAccessException();
                    }
                    else if (errorNum == NativeMethods.ERROR_INVALID_OWNER)
                    {
                        exception = new InvalidOperationException("Invalid owner");
                    }
                    else if (errorNum == NativeMethods.ERROR_INVALID_PRIMARY_GROUP)
                    {
                        exception = new InvalidOperationException("Invalid group");
                    }
                    else if (errorNum == NativeMethods.ERROR_INVALID_NAME)
                    {
                        exception = new ArgumentException("Invalid name", "name");
                    }
                    else if (errorNum == NativeMethods.ERROR_INVALID_HANDLE)
                    {
                        exception = new NotSupportedException("Invalid Handle");
                    }
                    else if (errorNum == NativeMethods.ERROR_FILE_NOT_FOUND)
                    {
                        exception = new FileNotFoundException();
                    }
                    else if (errorNum != NativeMethods.ERROR_NO_SECURITY_ON_OBJECT)
                    {
                        exception = new InvalidOperationException("Unexpected error");
                    }
                    else
                    {
                        exception = new NotSupportedException("No associated security");
                    }
                }
                throw exception;
            }
            //finally
            //{
            //security.WriteLUnlck();
            //}
        }
 public virtual AuthorizationRuleCollection GetAuditRules(bool includeExplicit, bool includeInherited, Type targetType)
 {
     return(_fileSystemSecurity.GetAuditRules(includeExplicit, includeInherited, targetType));
 }