/// <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)); } }
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))); } }
/// <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))); } }
/// <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); } }
/// <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)); } } }
/// <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)); } }
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))); } } }
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); }