/// <summary>
 /// Create a new AppContainerProfile.
 /// </summary>
 /// <param name="appcontainer_name">The name of the AppContainer.</param>
 /// <param name="display_name">A display name.</param>
 /// <param name="description">An optional description.</param>
 /// <param name="capabilities">An optional list of capability SIDs.</param>
 /// <param name="throw_on_error">True to throw on error.</param>
 /// <returns>The created AppContainer profile.</returns>
 /// <remarks>If the profile already exists then it'll be opened instead.</remarks>
 public static NtResult <AppContainerProfile> Create(
     string appcontainer_name,
     string display_name,
     string description,
     IEnumerable <Sid> capabilities,
     bool throw_on_error)
 {
     using (var resources = new DisposableList())
     {
         var      caps   = resources.CreateSidAndAttributes(capabilities);
         NtStatus status = Win32NativeMethods.CreateAppContainerProfile(appcontainer_name, display_name, description,
                                                                        caps.Length > 0 ? caps : null, caps.Length, out SafeSidBufferHandle sid);
         if (status == NtObjectUtils.MapDosErrorToStatus(Win32Error.ERROR_ALREADY_EXISTS))
         {
             return(new AppContainerProfile(appcontainer_name).CreateResult());
         }
         resources.AddResource(sid);
         return(status.CreateResult(throw_on_error, () =>
         {
             using (sid)
             {
                 return new AppContainerProfile(appcontainer_name, sid.ToSid(),
                                                capabilities, display_name, description);
             }
         }));
     }
 }
示例#2
0
        private static NtResult <SafeStructureInOutBuffer <T> > QueryObject <T>(SafeKernelObjectHandle handle,
                                                                                ObjectInformationClass object_info, bool throw_on_error) where T : new()
        {
            SafeStructureInOutBuffer <T> ret = null;
            NtStatus status = NtStatus.STATUS_BUFFER_TOO_SMALL;

            try
            {
                status = NtSystemCalls.NtQueryObject(handle, object_info, SafeHGlobalBuffer.Null, 0, out int return_length);
                if ((status != NtStatus.STATUS_BUFFER_TOO_SMALL) && (status != NtStatus.STATUS_INFO_LENGTH_MISMATCH))
                {
                    return(status.CreateResultFromError <SafeStructureInOutBuffer <T> >(throw_on_error));
                }

                if (return_length == 0)
                {
                    ret = new SafeStructureInOutBuffer <T>();
                }
                else
                {
                    ret = new SafeStructureInOutBuffer <T>(return_length, false);
                }
                status = NtSystemCalls.NtQueryObject(handle, object_info, ret, ret.Length, out return_length);
                return(status.CreateResult(throw_on_error, () => ret));
            }
            finally
            {
                if (ret != null && !status.IsSuccess())
                {
                    ret.Close();
                    ret = null;
                }
            }
        }
示例#3
0
        /// <summary>
        /// Determine if two addresses are the same mapped file.
        /// </summary>
        /// <param name="address_1">The first address.</param>
        /// <param name="address_2">The second address.</param>
        /// <param name="throw_on_error">True to throw on error.</param>
        /// <returns>True if the mapped memory is the same file.</returns>
        public static NtResult <bool> AreMappedFilesTheSame(long address_1, long address_2, bool throw_on_error)
        {
            NtStatus status = NtSystemCalls.NtAreMappedFilesTheSame(new IntPtr(address_1),
                                                                    new IntPtr(address_2));

            if (status == NtStatus.STATUS_NOT_SAME_DEVICE)
            {
                return(false.CreateResult());
            }
            return(status.CreateResult(throw_on_error, () => true));
        }
        /// <summary>
        /// Convert a DOS filename to an NT filename and get as an ObjectAttributes structure
        /// </summary>
        /// <param name="filename">The DOS filename.</param>
        /// <param name="attributes">The object attribute flags.</param>
        /// <param name="sqos">An optional security quality of service.</param>
        /// <param name="security_descriptor">An optional security descriptor.</param>
        /// <param name="throw_on_error">True to throw on error.</param>
        /// <returns>The object attributes</returns>
        public static NtResult <ObjectAttributes> DosFileNameToObjectAttributes(string filename, AttributeFlags attributes,
                                                                                SecurityQualityOfService sqos, SecurityDescriptor security_descriptor, bool throw_on_error)
        {
            if (filename == null)
            {
                throw new ArgumentNullException("filename");
            }

            UnicodeStringOut nt_name       = new UnicodeStringOut();
            RtlRelativeName  relative_name = new RtlRelativeName();

            try
            {
                NtStatus status = NtRtl.RtlDosPathNameToRelativeNtPathName_U_WithStatus(filename, out nt_name,
                                                                                        out IntPtr short_path, relative_name);
                if (!status.IsSuccess())
                {
                    return(status.CreateResultFromError <ObjectAttributes>(throw_on_error));
                }
                string final_name;
                SafeKernelObjectHandle root = SafeKernelObjectHandle.Null;

                if (relative_name.RelativeName.Buffer != IntPtr.Zero)
                {
                    final_name = relative_name.RelativeName.ToString();
                    root       = new SafeKernelObjectHandle(relative_name.ContainingDirectory, false);
                }
                else
                {
                    final_name = nt_name.ToString();
                }

                return(status.CreateResult(false, () =>
                                           new ObjectAttributes(final_name, attributes, root, sqos, security_descriptor)));
            }
            finally
            {
                if (nt_name.Buffer != IntPtr.Zero)
                {
                    NtRtl.RtlFreeUnicodeString(ref nt_name);
                }

                if (relative_name.RelativeName.Buffer != IntPtr.Zero)
                {
                    NtRtl.RtlReleaseRelativeName(relative_name);
                }
            }
        }
示例#5
0
        private static NtResult <List <Sid> > GetSids(SafeLsaHandle policy, string name, bool throw_on_error)
        {
            if (name is null)
            {
                throw new ArgumentNullException(nameof(name));
            }

            NtStatus status = SecurityNativeMethods.LsaEnumerateAccountsWithUserRight(policy, new UnicodeString(name),
                                                                                      out SafeLsaMemoryBuffer buffer, out int count);

            if (status == NtStatus.STATUS_NO_MORE_ENTRIES)
            {
                return(new List <Sid>().CreateResult());
            }
            return(status.CreateResult(throw_on_error, () => ParseSids(buffer, count)));
        }
        /// <summary>
        /// Enumerate accounts with a user right.
        /// </summary>
        /// <param name="user_right">The name of the user right.</param>
        /// <param name="throw_on_error">True to throw on error.</param>
        /// <returns>The list of SIDs with the user right.</returns>
        public NtResult <IReadOnlyList <Sid> > EnumerateAccountsWithUserRight(string user_right, bool throw_on_error)
        {
            if (user_right is null)
            {
                throw new ArgumentNullException(nameof(user_right));
            }

            NtStatus status = SecurityNativeMethods.LsaEnumerateAccountsWithUserRight(Handle,
                                                                                      new UnicodeString(user_right), out SafeLsaMemoryBuffer buffer, out int count);

            if (status == NtStatus.STATUS_NO_MORE_ENTRIES)
            {
                return(new List <Sid>().AsReadOnly().CreateResult <IReadOnlyList <Sid> >());
            }
            return(status.CreateResult(throw_on_error, () => ParseSids(buffer, count)));
        }
        /// <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 = Win32NativeMethods.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())
                    {
                        Win32NativeMethods.FreeInheritedFromArray(inherited_from, (ushort)inherited_from.Length, IntPtr.Zero);
                    }
                }
            }
        }
示例#8
0
        /// <summary>
        /// Get security descriptor as a byte array
        /// </summary>
        /// <param name="security_information">What parts of the security descriptor to retrieve</param>
        /// <param name="throw_on_error">True to throw on error.</param>
        /// <return>The NT status result and security descriptor.</return>
        public NtResult <byte[]> GetSecurityDescriptorBytes(SecurityInformation security_information, bool throw_on_error)
        {
            // Just do a check here, no point checking if ReadControl not available.
            if (!IsAccessMaskGranted(GenericAccessRights.ReadControl))
            {
                return(NtStatus.STATUS_ACCESS_DENIED.CreateResultFromError <byte[]>(throw_on_error));
            }

            NtStatus status = NtSystemCalls.NtQuerySecurityObject(Handle, security_information, null, 0, out int return_length);

            if (status != NtStatus.STATUS_BUFFER_TOO_SMALL)
            {
                return(status.CreateResult(throw_on_error, () => new byte[0]));
            }
            byte[] buffer = new byte[return_length];
            return(NtSystemCalls.NtQuerySecurityObject(Handle, security_information, buffer,
                                                       buffer.Length, out return_length).CreateResult(throw_on_error, () => buffer));
        }
示例#9
0
文件: NtWnf.cs 项目: codehz/winsilo
        /// <summary>
        /// Query state data for the WNF object.
        /// </summary>
        /// <param name="type_id">Optional Type ID.</param>
        /// <param name="explicit_scope">Optional explicit scope.</param>
        /// <param name="throw_on_error">True to throw on error.</param>
        /// <returns>The state data.</returns>
        public NtResult <WnfStateData> QueryStateData(WnfTypeId type_id, IntPtr explicit_scope, bool throw_on_error)
        {
            int tries = 10;
            int size  = 4096;

            while (tries-- > 0)
            {
                using (var buffer = new SafeHGlobalBuffer(size)) {
                    NtStatus status = NtSystemCalls.NtQueryWnfStateData(StateName, type_id,
                                                                        explicit_scope, out int changestamp, buffer, ref size);
                    if (status == NtStatus.STATUS_BUFFER_TOO_SMALL)
                    {
                        continue;
                    }

                    return(status.CreateResult(throw_on_error, () => new WnfStateData(buffer.ReadBytes(size), changestamp)));
                }
            }

            return(NtStatus.STATUS_BUFFER_TOO_SMALL.CreateResultFromError <WnfStateData>(throw_on_error));
        }
示例#10
0
        private NtResult <SafeHGlobalBuffer> CreateAbsoluteSecurityDescriptor(bool throw_on_error)
        {
            byte[] dacl       = Dacl?.ToByteArray();
            byte[] sacl       = Sacl?.ToByteArray();
            byte[] owner      = Owner?.Sid.ToArray();
            byte[] group      = Group?.Sid.ToArray();
            int    total_size = GetLength(dacl) + GetLength(sacl) + GetLength(owner) + GetLength(group);

            using (var sd_buffer = new SafeStructureInOutBuffer <SecurityDescriptorStructure>(total_size, true))
            {
                NtStatus status = NtRtl.RtlCreateSecurityDescriptor(sd_buffer, Revision);
                if (!status.IsSuccess())
                {
                    return(status.CreateResultFromError <SafeHGlobalBuffer>(throw_on_error));
                }

                SecurityDescriptorControl control = Control & SecurityDescriptorControl.ValidControlSetMask;
                status = NtRtl.RtlSetControlSecurityDescriptor(sd_buffer, control, control);
                if (!status.IsSuccess())
                {
                    return(status.CreateResultFromError <SafeHGlobalBuffer>(throw_on_error));
                }

                int current_ofs = 0;
                if (Dacl != null)
                {
                    IntPtr ptr = UpdateBuffer(sd_buffer, Dacl.NullAcl ? null : dacl, ref current_ofs);
                    status = NtRtl.RtlSetDaclSecurityDescriptor(sd_buffer, true, ptr, Dacl.Defaulted);
                    if (!status.IsSuccess())
                    {
                        return(status.CreateResultFromError <SafeHGlobalBuffer>(throw_on_error));
                    }
                }

                if (Sacl != null)
                {
                    IntPtr ptr = UpdateBuffer(sd_buffer, Sacl.NullAcl ? null : sacl, ref current_ofs);
                    status = NtRtl.RtlSetSaclSecurityDescriptor(sd_buffer, true, ptr, Sacl.Defaulted);
                    if (!status.IsSuccess())
                    {
                        return(status.CreateResultFromError <SafeHGlobalBuffer>(throw_on_error));
                    }
                }

                if (Owner != null)
                {
                    IntPtr ptr = UpdateBuffer(sd_buffer, owner, ref current_ofs);
                    status = NtRtl.RtlSetOwnerSecurityDescriptor(sd_buffer, ptr, Owner.Defaulted);
                    if (!status.IsSuccess())
                    {
                        return(status.CreateResultFromError <SafeHGlobalBuffer>(throw_on_error));
                    }
                }

                if (Group != null)
                {
                    IntPtr ptr = UpdateBuffer(sd_buffer, group, ref current_ofs);
                    status = NtRtl.RtlSetGroupSecurityDescriptor(sd_buffer, ptr, Group.Defaulted);
                    if (!status.IsSuccess())
                    {
                        return(status.CreateResultFromError <SafeHGlobalBuffer>(throw_on_error));
                    }
                }

                return(status.CreateResult <SafeHGlobalBuffer>(throw_on_error, () => sd_buffer.Detach()));
            }
        }