/// <summary> /// Set security using a named object. /// </summary> /// <param name="name">The name of the object.</param> /// <param name="type">The type of named object.</param> /// <param name="security_information">The security information to set.</param> /// <param name="security_descriptor">The security descriptor to set.</param> /// <param name="throw_on_error">True to throw on error.</param> /// <returns>The NT status code.</returns> public static NtStatus SetSecurityInfo(string name, SeObjectType type, SecurityInformation security_information, SecurityDescriptor security_descriptor, bool throw_on_error) { return(SecurityNativeMethods.SetNamedSecurityInfo( name, type, security_information, security_descriptor.Owner?.Sid.ToArray(), security_descriptor.Group?.Sid.ToArray(), security_descriptor.Dacl?.ToByteArray(), security_descriptor.Sacl?.ToByteArray()).ToNtException(throw_on_error)); }
/// <summary> /// Get an authentication package by name. /// </summary> /// <param name="package">The name of the package.</param> /// <returns>The authentication package.</returns> public static AuthenticationPackage FromName(string package) { SecurityNativeMethods.QuerySecurityPackageInfo(package, out IntPtr package_info).CheckResult(); try { return(new AuthenticationPackage((SecPkgInfo)Marshal.PtrToStructure(package_info, typeof(SecPkgInfo)))); } finally { SecurityNativeMethods.FreeContextBuffer(package_info); } }
/// <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); } } } }
/// <summary> /// Get the security descriptor for a named resource. /// </summary> /// <param name="name">The name of the resource.</param> /// <param name="type">The type of the resource.</param> /// <param name="security_information">The security information to get.</param> /// <param name="throw_on_error">True to throw on error.</param> /// <returns>The security descriptor.</returns> public static NtResult <SecurityDescriptor> GetSecurityInfo( string name, SeObjectType type, SecurityInformation security_information, bool throw_on_error) { using (var result = SecurityNativeMethods.GetNamedSecurityInfo(name, type, security_information, null, null, null, null, out SafeLocalAllocBuffer sd).MapDosErrorToStatus().CreateResult(throw_on_error, () => sd)) { if (!result.IsSuccess) { return(result.Cast <SecurityDescriptor>()); } return(SecurityDescriptor.Parse(result.Result, GetNativeType(type), throw_on_error)); } }
/// <summary> /// Set security using a named object. /// </summary> /// <param name="name">The name of the object.</param> /// <param name="type">The type of named object.</param> /// <param name="security_information">The security information to set.</param> /// <param name="security_descriptor">The security descriptor to set.</param> /// <param name="invoke_setting">Specify to indicate when to execute progress function.</param> /// <param name="action">The security operation to perform on the tree.</param> /// <param name="progress_function">Progress function.</param> /// <param name="throw_on_error">True to throw on error.</param> /// <returns>The NT status code.</returns> public static NtStatus SetSecurityInfo(string name, SeObjectType type, SecurityInformation security_information, SecurityDescriptor security_descriptor, TreeSecInfo action, TreeProgressFunction progress_function, ProgressInvokeSetting invoke_setting, bool throw_on_error) { return(SecurityNativeMethods.TreeSetNamedSecurityInfo( name, type, security_information, security_descriptor.Owner?.Sid.ToArray(), security_descriptor.Group?.Sid.ToArray(), security_descriptor.Dacl?.ToByteArray(), security_descriptor.Sacl?.ToByteArray(), action, CreateCallback(progress_function), invoke_setting, IntPtr.Zero ).ToNtException(throw_on_error)); }
/// <summary> /// Convert SPN to a string. /// </summary> /// <returns>The SPN string.</returns> public override string ToString() { int length = 0; Win32Error err = SecurityNativeMethods.DsMakeSpn(ServiceClass, ServiceName, InstanceName, (ushort)InstancePort, Referrer, ref length, null); if (err == Win32Error.SUCCESS) { return(string.Empty); } if (err != Win32Error.ERROR_BUFFER_OVERFLOW) { throw new NtException(err.MapDosErrorToStatus()); } StringBuilder builder = new StringBuilder(length); SecurityNativeMethods.DsMakeSpn(ServiceClass, ServiceName, InstanceName, (ushort)InstancePort, Referrer, ref length, builder).ToNtException(); return(builder.ToString()); }
private static NtStatus LsaStorePrivateDataInternal(string system_name, string keyname, byte[] data, bool throw_on_error) { if (keyname is null) { throw new ArgumentNullException(nameof(keyname)); } using (var policy = SafeLsaHandle.OpenPolicy(system_name, Policy.LsaPolicyAccessRights.CreateSecret, throw_on_error)) { if (!policy.IsSuccess) { return(policy.Status); } using (var data_buffer = data == null ? UnicodeStringBytesSafeBuffer.Null : new UnicodeStringBytesSafeBuffer(data)) { return(SecurityNativeMethods.LsaStorePrivateData(policy.Result, new UnicodeString(keyname), data_buffer)); } } }
/// <summary> /// Remove a SID to name mapping with LSA. /// </summary> /// <param name="domain">The domain name for the SID.</param> /// <param name="name">The account name for the SID. Can be null for a domain SID.</param> /// <param name="throw_on_error">True to throw on error.</param> /// <returns>The NT status result.</returns> public static NtStatus RemoveSidNameMapping(string domain, string name, bool throw_on_error) { LSA_SID_NAME_MAPPING_OPERATION_REMOVE_INPUT input = new LSA_SID_NAME_MAPPING_OPERATION_REMOVE_INPUT { DomainName = new UnicodeStringIn(domain) }; if (name != null) { 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_Remove, input_buffer, out output).ToNtException(throw_on_error)); } finally { output?.Dispose(); } } }
/// <summary> /// Try and parse an SPN string to a class. /// </summary> /// <param name="spn">The SPN string.</param> /// <param name="result">The result class.</param> /// <returns>True if the SPN was parsed successfully.</returns> /// <exception cref="FormatException">Thrown in invalid SPN.</exception> public static bool TryParse(string spn, out ServicePrincipalName result) { result = null; OptionalInt32 cServiceClass = 1; StringBuilder ServiceClass = new StringBuilder(1); OptionalInt32 cServiceName = 1; StringBuilder ServiceName = new StringBuilder(1); OptionalInt32 cInstanceName = 1; StringBuilder InstanceName = new StringBuilder(1); OptionalUInt16 InstancePort = 0; var err = SecurityNativeMethods.DsCrackSpn(spn, cServiceClass, ServiceClass, cServiceName, ServiceName, cInstanceName, InstanceName, InstancePort); if (err != Win32Error.ERROR_BUFFER_OVERFLOW) { return(false); } ServiceClass = new StringBuilder(cServiceClass.Value); ServiceName = new StringBuilder(cServiceName.Value); InstanceName = new StringBuilder(cInstanceName.Value); if (SecurityNativeMethods.DsCrackSpn(spn, cServiceClass, ServiceClass, cServiceName, ServiceName, cInstanceName, InstanceName, InstancePort) != Win32Error.SUCCESS) { return(false); } result = new ServicePrincipalName() { ServiceClass = ServiceClass.ToString(), ServiceName = ServiceName.ToString(), InstanceName = InstanceName.ToString(), InstancePort = InstancePort.Value }; return(true); }
/// <summary> /// Get authentication packages. /// </summary> /// <returns>The list of authentication packages.</returns> public static IEnumerable <AuthenticationPackage> Get() { List <AuthenticationPackage> packages = new List <AuthenticationPackage>(); if (SecurityNativeMethods.EnumerateSecurityPackages(out int count, out IntPtr ppPackageInfo) == SecStatusCode.Success) { try { int size = Marshal.SizeOf(typeof(SecPkgInfo)); for (int i = 0; i < count; ++i) { SecPkgInfo pkg = (SecPkgInfo)Marshal.PtrToStructure(ppPackageInfo + i * size, typeof(SecPkgInfo)); packages.Add(new AuthenticationPackage(pkg)); } } finally { SecurityNativeMethods.FreeContextBuffer(ppPackageInfo); } } return(packages.AsReadOnly()); }
/// <summary> /// Get the security descriptor for a resource. /// </summary> /// <param name="handle">The handle to the resource.</param> /// <param name="type">The type of the resource.</param> /// <param name="security_information">The security information to get.</param> /// <param name="throw_on_error">True to throw on error.</param> /// <returns>The security descriptor.</returns> public static NtResult <SecurityDescriptor> GetSecurityInfo( SafeHandle handle, SeObjectType type, SecurityInformation security_information, bool throw_on_error) { using (var result = SecurityNativeMethods.GetSecurityInfo(handle, type, security_information, null, null, null, null, out SafeLocalAllocBuffer sd).MapDosErrorToStatus().CreateResult(throw_on_error, () => sd)) { if (!result.IsSuccess) { return(result.Cast <SecurityDescriptor>()); } NtType sd_type = null; if (handle is SafeKernelObjectHandle kernel_handle) { sd_type = NtType.GetTypeByName(kernel_handle.NtTypeName, false); } return(SecurityDescriptor.Parse(result.Result, sd_type ?? GetNativeType(type), 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(); } } } }
private bool GenClientContext(byte[] token) { using (DisposableList list = new DisposableList()) { SecStatusCode result = 0; SecBuffer out_sec_buffer = list.AddResource(new SecBuffer(SecBufferType.Token, 8192)); SecBufferDesc out_buffer_desc = list.AddResource(new SecBufferDesc(out_sec_buffer)); InitializeContextRetFlags flags; LargeInteger expiry = new LargeInteger(); if (token != null) { SecBuffer in_sec_buffer = list.AddResource(new SecBuffer(SecBufferType.Token, token)); SecBufferDesc in_buffer_desc = list.AddResource(new SecBufferDesc(in_sec_buffer)); result = SecurityNativeMethods.InitializeSecurityContext(_creds.CredHandle, _context, _target, _req_attributes, 0, _data_rep, in_buffer_desc, 0, _context, out_buffer_desc, out flags, expiry).CheckResult(); Flags = flags; } else { result = SecurityNativeMethods.InitializeSecurityContext(_creds.CredHandle, null, _target, _req_attributes, 0, _data_rep, null, 0, _context, out_buffer_desc, out flags, expiry).CheckResult(); } Expiry = expiry.QuadPart; Flags = flags; if (result == SecStatusCode.CompleteNeeded || result == SecStatusCode.CompleteAndContinue) { SecurityNativeMethods.CompleteAuthToken(_context, out_buffer_desc).CheckResult(); } Token = out_buffer_desc.ToArray()[0].ToArray(); return(!(result == SecStatusCode.ContinueNeeded || result == SecStatusCode.CompleteAndContinue)); } }
private bool GenServerContext( bool new_context, byte[] token) { using (DisposableList list = new DisposableList()) { SecBuffer out_sec_buffer = list.AddResource(new SecBuffer(SecBufferType.Token, 8192)); SecBufferDesc out_buffer_desc = list.AddResource(new SecBufferDesc(out_sec_buffer)); SecBuffer in_sec_buffer = list.AddResource(new SecBuffer(SecBufferType.Token, token)); SecBufferDesc in_buffer_desc = list.AddResource(new SecBufferDesc(in_sec_buffer)); LargeInteger expiry = new LargeInteger(); SecStatusCode result = SecurityNativeMethods.AcceptSecurityContext(_creds.CredHandle, new_context ? null : _context, in_buffer_desc, _req_flags, _data_rep, _context, out_buffer_desc, out AcceptContextRetFlags context_attr, expiry).CheckResult(); Flags = context_attr; Expiry = expiry.QuadPart; if (result == SecStatusCode.CompleteNeeded || result == SecStatusCode.CompleteAndContinue) { SecurityNativeMethods.CompleteAuthToken(_context, out_buffer_desc).CheckResult(); } Token = out_buffer_desc.ToArray()[0].ToArray(); return(!(result == SecStatusCode.ContinueNeeded || result == SecStatusCode.CompleteAndContinue)); } }
/// <summary> /// Impersonate the security context. /// </summary> /// <returns>The disposable context to revert the impersonation.</returns> public AuthenticationImpersonationContext Impersonate() { SecurityNativeMethods.ImpersonateSecurityContext(_context).CheckResult(); return(new AuthenticationImpersonationContext(_context)); }
/// <summary> /// Dispose. /// </summary> public void Dispose() { SecurityNativeMethods.FreeCredentialsHandle(CredHandle); }
void IDisposable.Dispose() { SecurityNativeMethods.DeleteSecurityContext(_context); }
void IDisposable.Dispose() { SecurityNativeMethods.RevertSecurityContext(_context); }
/// <summary> /// Get an access token for the authenticated user. /// </summary> /// <returns>The user's access token.</returns> public NtToken GetAccessToken() { SecurityNativeMethods.QuerySecurityContextToken(_context, out SafeKernelObjectHandle token).CheckResult(); return(NtToken.FromHandle(token)); }