예제 #1
0
        /// <summary>
        /// Get the source of inherited ACEs.
        /// </summary>
        /// <param name="name">The name of the resource.</param>
        /// <param name="type">The type of the resource.</param>
        /// <param name="container">Whether the resource is a container.</param>
        /// <param name="object_types">Optional list of object types.</param>
        /// <param name="security_descriptor">The security descriptor for the resource.</param>
        /// <param name="sacl">True to check the SACL otherwise checks the DACL.</param>
        /// <param name="generic_mapping">Generic mapping for the resource.</param>
        /// <param name="query_security">Query security descriptors for sources.</param>
        /// <param name="throw_on_error">True to throw on error.</param>
        /// <returns>The list of inheritance sources.</returns>
        public static NtResult <IEnumerable <SecurityDescriptorInheritanceSource> > GetInheritanceSource(
            string name,
            SeObjectType type,
            bool container,
            Guid[] object_types,
            SecurityDescriptor security_descriptor,
            bool sacl,
            GenericMapping generic_mapping,
            bool query_security,
            bool throw_on_error)
        {
            Acl acl = sacl ? security_descriptor.Sacl : security_descriptor.Dacl;

            if (acl == null || acl.NullAcl)
            {
                return(NtStatus.STATUS_INVALID_ACL.CreateResultFromError <IEnumerable <SecurityDescriptorInheritanceSource> >(throw_on_error));
            }

            using (var list = new DisposableList())
            {
                SafeGuidArrayBuffer guids = SafeGuidArrayBuffer.Null;
                if (object_types?.Length > 0)
                {
                    guids = list.AddResource(new SafeGuidArrayBuffer(object_types));
                }

                NtType native_type = GetNativeType(type);

                INHERITED_FROM[] inherited_from = new INHERITED_FROM[acl.Count];
                NtStatus         status         = NtStatus.STATUS_INVALID_PARAMETER;
                try
                {
                    status = SecurityNativeMethods.GetInheritanceSource(name, type, sacl ? SecurityInformation.Sacl : SecurityInformation.Dacl,
                                                                        container, guids, guids.Count, acl.ToByteArray(), IntPtr.Zero, ref generic_mapping, inherited_from).MapDosErrorToStatus();
                    return(status.CreateResult(throw_on_error, () => (IEnumerable <SecurityDescriptorInheritanceSource>)inherited_from
                                               .Select((s, i) => new SecurityDescriptorInheritanceSource(acl[i], s, type,
                                                                                                         native_type, container, query_security, sacl)).Where(s => s.Depth != -1).ToArray()));
                }
                finally
                {
                    if (status.IsSuccess())
                    {
                        SecurityNativeMethods.FreeInheritedFromArray(inherited_from, (ushort)inherited_from.Length, IntPtr.Zero);
                    }
                }
            }
        }