/// <summary>
 /// Modify trace security.
 /// </summary>
 /// <param name="guid">The event trace GUID.</param>
 /// <param name="operation">The operation to perform.</param>
 /// <param name="sid">The SID to set.</param>
 /// <param name="access_mask">The access mask to set.</param>
 /// <param name="allow">True to allow, false to deny.</param>
 /// <param name="throw_on_error">True to throw on error.</param>
 /// <returns>The NT status code.</returns>
 public static NtStatus ControlTraceSecurity(Guid guid, EventSecurityOperation operation, Sid sid, TraceAccessRights access_mask, bool allow, bool throw_on_error)
 {
     using (var buffer = sid.ToSafeBuffer())
     {
         return(Win32NativeMethods.EventAccessControl(ref guid, operation, buffer, access_mask, allow).ToNtException(throw_on_error));
     }
 }
        /// <summary>
        /// Add a SID to name mapping with LSA.
        /// </summary>
        /// <param name="domain">The domain name for the SID. The SID must be in the NT authority.</param>
        /// <param name="name">The account name for the SID. Can be null for a domain SID.</param>
        /// <param name="sid">The SID to add.</param>
        /// <param name="throw_on_error">True to throw on error.</param>
        /// <returns>The NT status result.</returns>
        public static NtStatus AddSidNameMapping(string domain, string name, Sid sid, bool throw_on_error)
        {
            using (var sid_buffer = sid.ToSafeBuffer())
            {
                LSA_SID_NAME_MAPPING_OPERATION_ADD_INPUT input = new LSA_SID_NAME_MAPPING_OPERATION_ADD_INPUT
                {
                    Sid        = sid_buffer.DangerousGetHandle(),
                    DomainName = new UnicodeStringIn(domain)
                };
                if (!string.IsNullOrEmpty(name))
                {
                    input.AccountName = new UnicodeStringIn(name);
                }

                using (var input_buffer = input.ToBuffer())
                {
                    SafeLsaMemoryBuffer output = null;
                    try
                    {
                        return(SecurityNativeMethods.LsaManageSidNameMapping(LSA_SID_NAME_MAPPING_OPERATION_TYPE.LsaSidNameMappingOperation_Add,
                                                                             input_buffer, out output).ToNtException(throw_on_error));
                    }
                    finally
                    {
                        output?.Dispose();
                    }
                }
            }
        }
        internal static NtStatus RemoveAccountRights(string system_name, Sid sid, bool remove_all, IEnumerable <string> account_rights, bool throw_on_error)
        {
            if (sid is null)
            {
                throw new ArgumentNullException(nameof(sid));
            }

            if (account_rights is null)
            {
                throw new ArgumentNullException(nameof(account_rights));
            }

            var rights = account_rights.Select(s => new UnicodeStringIn(s)).ToArray();

            if (!account_rights.Any())
            {
                return(NtStatus.STATUS_SUCCESS);
            }

            using (var policy = SafeLsaHandle.OpenPolicy(system_name, LsaPolicyAccessRights.LookupNames, throw_on_error))
            {
                if (!policy.IsSuccess)
                {
                    return(policy.Status);
                }
                using (var sid_buffer = sid.ToSafeBuffer())
                {
                    return(SecurityNativeMethods.LsaRemoveAccountRights(policy.Result,
                                                                        sid_buffer, remove_all, rights, rights.Length).ToNtException(throw_on_error));
                }
            }
        }
        /// <summary>
        /// Remove account rights from an account.
        /// </summary>
        /// <param name="sid">The SID of the account.</param>
        /// <param name="remove_all">True to remove all rights.</param>
        /// <param name="account_rights">The account rights to add.</param>
        /// <param name="throw_on_error">True to throw on error.</param>
        /// <returns>The NT status code.</returns>
        public NtStatus RemoveAccountRights(Sid sid, bool remove_all, IEnumerable <string> account_rights, bool throw_on_error)
        {
            if (sid is null)
            {
                throw new ArgumentNullException(nameof(sid));
            }

            if (account_rights is null)
            {
                throw new ArgumentNullException(nameof(account_rights));
            }

            var rights = account_rights.Select(s => new UnicodeStringIn(s)).ToArray();

            if (!account_rights.Any() && !remove_all)
            {
                return(NtStatus.STATUS_SUCCESS);
            }

            using (var sid_buffer = sid.ToSafeBuffer())
            {
                return(SecurityNativeMethods.LsaRemoveAccountRights(Handle,
                                                                    sid_buffer, remove_all, rights, rights.Length).ToNtException(throw_on_error));
            }
        }
Beispiel #5
0
 private NtResult <SamDomain> OpenDomain(string domain_name, Sid domain_id, SamDomainAccessRights desired_access, bool throw_on_error)
 {
     using (var buffer = domain_id.ToSafeBuffer())
     {
         return(SecurityNativeMethods.SamOpenDomain(Handle, desired_access, buffer,
                                                    out SafeSamHandle domain_handle).CreateResult(throw_on_error,
                                                                                                  () => new SamDomain(domain_handle, desired_access, ServerName, domain_name, domain_id)));
     }
 }
 /// <summary>
 /// Create an LSA account object.
 /// </summary>
 /// <param name="sid">The SID of the account.</param>
 /// <param name="desired_access">The desired access for the account.</param>
 /// <param name="throw_on_error">True to throw on error.</param>
 /// <returns>The created account.</returns>
 public NtResult <LsaAccount> CreateAccount(Sid sid, LsaAccountAccessRights desired_access, bool throw_on_error)
 {
     using (var buffer = sid.ToSafeBuffer())
     {
         return(SecurityNativeMethods.LsaCreateAccount(Handle, buffer,
                                                       desired_access, out SafeLsaHandle handle).CreateResult(throw_on_error,
                                                                                                              () => new LsaAccount(handle, desired_access, sid)));
     }
 }
Beispiel #7
0
        /// <summary>
        /// Perform an Access Check.
        /// </summary>
        /// <param name="sd">The security descriptor for the check.</param>
        /// <param name="optional_sd">Optional list of security descriptors to merge.</param>
        /// <param name="desired_access">The desired access.</param>
        /// <param name="principal">Optional Principal SID.</param>
        /// <param name="object_types">Optional list of object types.</param>
        /// <param name="type">NT Type for access checking.</param>
        /// <param name="throw_on_error">True to throw on error.</param>
        /// <returns>The list of access check results.</returns>
        /// <remarks>The list of object types is restricted to 256 entries for remote access checks.</remarks>
        public NtResult <AuthZAccessCheckResult[]> AccessCheck(SecurityDescriptor sd, IEnumerable <SecurityDescriptor> optional_sd,
                                                               AccessMask desired_access, Sid principal, IEnumerable <ObjectTypeEntry> object_types, NtType type,
                                                               bool throw_on_error)
        {
            if (sd is null)
            {
                throw new ArgumentNullException(nameof(sd));
            }

            if (type is null)
            {
                throw new ArgumentNullException(nameof(type));
            }

            using (var list = new DisposableList())
            {
                AUTHZ_ACCESS_REQUEST request = new AUTHZ_ACCESS_REQUEST();
                request.DesiredAccess = desired_access;
                if (principal != null)
                {
                    request.PrincipalSelfSid = list.AddResource(principal.ToSafeBuffer()).DangerousGetHandle();
                }

                int result_count = 1;
                var object_list  = NtSecurity.ConvertObjectTypes(object_types, list);
                if (object_list?.Length > 0)
                {
                    result_count                 = object_list.Length;
                    request.ObjectTypeList       = list.AddResource(object_list.ToBuffer()).DangerousGetHandle();
                    request.ObjectTypeListLength = object_list.Length;
                }
                var      sd_buffer           = list.AddResource(sd.ToSafeBuffer());
                int      optional_sd_count   = optional_sd?.Count() ?? 0;
                IntPtr[] optional_sd_buffers = null;
                if (optional_sd_count > 0)
                {
                    optional_sd_buffers = optional_sd.Select(s => list.AddResource(s.ToSafeBuffer()).DangerousGetHandle()).ToArray();
                }
                AUTHZ_ACCESS_REPLY reply = new AUTHZ_ACCESS_REPLY();
                reply.ResultListLength = result_count;
                var error_buffer = list.AddResource(new int[result_count].ToBuffer());
                reply.Error = error_buffer.DangerousGetHandle();
                var access_buffer = list.AddResource(new AccessMask[result_count].ToBuffer());
                reply.GrantedAccessMask = access_buffer.DangerousGetHandle();
                var audit_buffer = list.AddResource(new int[result_count].ToBuffer());
                reply.SaclEvaluationResults = audit_buffer.DangerousGetHandle();

                return(SecurityNativeMethods.AuthzAccessCheck(AuthZAccessCheckFlags.None, _handle,
                                                              ref request, IntPtr.Zero, sd_buffer, optional_sd_buffers, optional_sd_count,
                                                              ref reply, IntPtr.Zero).CreateWin32Result(throw_on_error,
                                                                                                        () => CreateResult(result_count, error_buffer, access_buffer, object_types?.ToArray(), type)));
            }
        }
        /// <summary>
        /// Enumerate account rights for a SID.
        /// </summary>
        /// <param name="sid">The SID to enumerate for.</param>
        /// <param name="throw_on_error">True to throw on error.</param>
        /// <returns>The list of assigned account rights.</returns>
        public NtResult <IReadOnlyList <string> > EnumerateAccountRights(Sid sid, bool throw_on_error)
        {
            if (sid is null)
            {
                throw new ArgumentNullException(nameof(sid));
            }

            using (var sid_buffer = sid.ToSafeBuffer())
            {
                return(SecurityNativeMethods.LsaEnumerateAccountRights(Handle, sid_buffer,
                                                                       out SafeLsaMemoryBuffer buffer, out int count)
                       .CreateResult(throw_on_error, () => ParseRights(buffer, count)));
            }
        }
        /// <summary>
        /// Open trusted domain object.
        /// </summary>
        /// <param name="sid">The SID of the trusted domain.</param>
        /// <param name="desired_access">The desired access for the object.</param>
        /// <param name="throw_on_error">True to throw on error.</param>
        /// <returns>The trusted domain object.</returns>
        public NtResult <LsaTrustedDomain> OpenTrustedDomain(Sid sid, LsaTrustedDomainAccessRights desired_access, bool throw_on_error)
        {
            if (sid is null)
            {
                throw new ArgumentNullException(nameof(sid));
            }

            using (var sid_buffer = sid.ToSafeBuffer())
            {
                return(SecurityNativeMethods.LsaOpenTrustedDomain(Handle, sid_buffer,
                                                                  desired_access, out SafeLsaHandle handle).CreateResult(throw_on_error,
                                                                                                                         () => new LsaTrustedDomain(handle, desired_access, null, sid, QueryDomainInfo(sid_buffer), SystemName)));
            }
        }
Beispiel #10
0
 /// <summary>
 /// Set AppContainer Information to Context.
 /// </summary>
 /// <param name="package_sid">The package SID.</param>
 /// <param name="capabilities">List of capabilities.</param>
 /// <param name="throw_on_error">True to throw on error</param>
 /// <returns>The NT status code.</returns>
 public NtStatus SetAppContainer(Sid package_sid, IEnumerable <UserGroup> capabilities, bool throw_on_error)
 {
     using (var list = new DisposableList()) {
         var sid_buffer = list.AddResource(package_sid.ToSafeBuffer());
         var cap_sids   = capabilities?.ToArray() ?? new UserGroup[0];
         SafeTokenGroupsBuffer cap_buffer = list.AddResource(SafeTokenGroupsBuffer.Create(cap_sids));
         SafeBuffer            buffer     = cap_sids.Length > 0 ? cap_buffer.Data : SafeHGlobalBuffer.Null;
         if (!SecurityNativeMethods.AuthzSetAppContainerInformation(_handle,
                                                                    sid_buffer, cap_sids.Length, buffer))
         {
             return(NtObjectUtils.MapDosErrorToStatus().ToNtException(throw_on_error));
         }
         return(NtStatus.STATUS_SUCCESS);
     }
 }
Beispiel #11
0
        /// <summary>
        /// Derive a restricted package sid from an existing pacakge sid.
        /// </summary>
        /// <param name="package_sid">The base package sid.</param>
        /// <param name="restricted_name">The restricted name for the sid.</param>
        /// <returns>The derived Sid.</returns>
        public static Sid DeriveRestrictedPackageSidFromSid(Sid package_sid, string restricted_name)
        {
            using (var sid_buf = package_sid.ToSafeBuffer())
            {
                int hr = Win32NativeMethods.DeriveRestrictedAppContainerSidFromAppContainerSidAndRestrictedName(sid_buf, restricted_name, out SafeSidBufferHandle sid);
                if (hr != 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }

                using (sid)
                {
                    return(new Sid(sid));
                }
            }
        }
Beispiel #12
0
 /// <summary>
 /// Derive a restricted package sid from an existing pacakge sid.
 /// </summary>
 /// <param name="package_sid">The base package sid.</param>
 /// <param name="restricted_name">The restricted name for the sid.</param>
 /// <param name="throw_on_error">True to throw on error.</param>
 /// <returns>The derived Sid.</returns>
 public static NtResult <Sid> DeriveRestrictedPackageSidFromSid(Sid package_sid, string restricted_name, bool throw_on_error)
 {
     using (var sid_buf = package_sid.ToSafeBuffer()) {
         int hr = Win32NativeMethods.DeriveRestrictedAppContainerSidFromAppContainerSidAndRestrictedName(sid_buf,
                                                                                                         restricted_name, out SafeSidBufferHandle sid);
         if (hr == 0)
         {
             using (sid) {
                 Sid result = new Sid(sid);
                 NtSecurity.CacheSidName(result, string.Empty, $"{package_sid.Name}/{restricted_name}",
                                         SidNameSource.Package, SidNameUse.User);
                 return(result.CreateResult());
             }
         }
         return(((NtStatus)hr).CreateResultFromError <Sid>(throw_on_error));
     }
 }
Beispiel #13
0
        internal static NtResult <IEnumerable <AccountRight> > GetAccountRights(string system_name, Sid sid, bool throw_on_error)
        {
            if (sid is null)
            {
                throw new ArgumentNullException(nameof(sid));
            }

            using (var policy = SafeLsaHandle.OpenPolicy(system_name, LsaPolicyAccessRights.GenericExecute, throw_on_error)) {
                if (!policy.IsSuccess)
                {
                    return(policy.Cast <IEnumerable <AccountRight> >());
                }
                using (var sid_buffer = sid.ToSafeBuffer()) {
                    return(SecurityNativeMethods.LsaEnumerateAccountRights(policy.Result, sid_buffer,
                                                                           out SafeLsaMemoryBuffer buffer, out int count)
                           .CreateResult(throw_on_error, () => ParseRights(policy.Result, system_name, buffer, count)));
                }
            }
        }
Beispiel #14
0
        internal static SECURITY_CAPABILITIES CreateSecuityCapabilities(Sid package_sid, IEnumerable <Sid> capabilities, DisposableList resources)
        {
            SECURITY_CAPABILITIES caps = new SECURITY_CAPABILITIES {
                AppContainerSid = resources.AddResource(package_sid.ToSafeBuffer()).DangerousGetHandle()
            };

            if (capabilities.Any())
            {
                SidAndAttributes[] cap_sids = capabilities.Select(s => new SidAndAttributes()
                {
                    Sid        = resources.AddResource(s.ToSafeBuffer()).DangerousGetHandle(),
                    Attributes = GroupAttributes.Enabled
                }).ToArray();

                SafeHGlobalBuffer cap_buffer = resources.AddResource(new SafeHGlobalBuffer(Marshal.SizeOf(typeof(SidAndAttributes)) * cap_sids.Length));
                cap_buffer.WriteArray(0, cap_sids, 0, cap_sids.Length);
                caps.Capabilities    = cap_buffer.DangerousGetHandle();
                caps.CapabilityCount = cap_sids.Length;
            }

            return(caps);
        }