From 45e737fa728bafc13e686bb339eb3ac3ea6955ef Mon Sep 17 00:00:00 2001 From: Ilya Date: Mon, 1 Nov 2021 21:55:13 +0500 Subject: [PATCH 1/2] Rid of TypeResolver.ResolveType() call from Process_Types_Ps1Xml() --- .../security/AclCommands.cs | 485 +---------------- .../engine/InitialSessionState.cs | 7 - .../SecurityDescriptorCommandsHelperBase.cs | 502 ++++++++++++++++++ .../engine/TypeTable_Types_Ps1Xml.cs | 13 +- 4 files changed, 512 insertions(+), 495 deletions(-) create mode 100644 src/System.Management.Automation/engine/SecurityDescriptorCommandsHelperBase.cs diff --git a/src/Microsoft.PowerShell.Security/security/AclCommands.cs b/src/Microsoft.PowerShell.Security/security/AclCommands.cs index c0994a57a53..41f85ed8c90 100644 --- a/src/Microsoft.PowerShell.Security/security/AclCommands.cs +++ b/src/Microsoft.PowerShell.Security/security/AclCommands.cs @@ -14,7 +14,8 @@ using System.Management.Automation.Security; using System.Runtime.InteropServices; using System.Security.AccessControl; -using System.Security.Principal; + +using Microsoft.PowerShell.Commands.Internal; using Dbg = System.Management.Automation; @@ -24,7 +25,7 @@ namespace Microsoft.PowerShell.Commands /// Defines the base class from which all Security Descriptor commands /// are derived. /// - public abstract class SecurityDescriptorCommandsBase : PSCmdlet + public abstract class SecurityDescriptorCommandsBase : SecurityDescriptorCommandsHelperBase { /// /// Gets or sets the filter property. The filter @@ -103,486 +104,6 @@ internal CmdletProviderContext CmdletProviderContext } } - #region brokered properties - - /// - /// Add brokered properties for easy access to important properties - /// of security descriptor. - /// - internal static void AddBrokeredProperties( - Collection results, - bool audit, - bool allCentralAccessPolicies) - { - foreach (PSObject result in results) - { - if (audit) - { - // Audit - result.Properties.Add - ( - new PSCodeProperty - ( - "Audit", - typeof(SecurityDescriptorCommandsBase).GetMethod("GetAudit") - ) - ); - } - // CentralAccessPolicyId retrieval does not require elevation, so we always add this property. - result.Properties.Add - ( - new PSCodeProperty - ( - "CentralAccessPolicyId", - typeof(SecurityDescriptorCommandsBase).GetMethod("GetCentralAccessPolicyId") - ) - ); -#if !CORECLR // GetAllCentralAccessPolicies and GetCentralAccessPolicyName are not supported in OneCore powershell - // because function 'LsaQueryCAPs' is not available in OneCoreUAP and NanoServer. - if (allCentralAccessPolicies) - { - // AllCentralAccessPolicies - result.Properties.Add - ( - new PSCodeProperty - ( - "AllCentralAccessPolicies", - typeof(SecurityDescriptorCommandsBase).GetMethod("GetAllCentralAccessPolicies") - ) - ); - } - // CentralAccessPolicyName retrieval does not require elevation, so we always add this property. - result.Properties.Add - ( - new PSCodeProperty - ( - "CentralAccessPolicyName", - typeof(SecurityDescriptorCommandsBase).GetMethod("GetCentralAccessPolicyName") - ) - ); -#endif - } - } - - /// - /// Gets the Path of the provided PSObject. - /// - /// - /// The PSObject for which to obtain the path. - /// - /// - /// The path of the provided PSObject. - /// - public static string GetPath(PSObject instance) - { - if (instance == null) - { - throw PSTraceSource.NewArgumentNullException(nameof(instance)); - } - else - { - // These are guaranteed to not be null, but even checking - // them for null causes a presharp warning -#pragma warning disable 56506 - - // Get path - return instance.Properties["PSPath"].Value.ToString(); -#pragma warning restore 56506 - } - } - - /// - /// Gets the Owner of the provided PSObject. - /// - /// - /// The PSObject for which to obtain the Owner. - /// - /// - /// The Owner of the provided PSObject. - /// - public static string GetOwner(PSObject instance) - { - if (instance == null) - { - throw PSTraceSource.NewArgumentNullException(nameof(instance)); - } - - if (!(instance.BaseObject is ObjectSecurity sd)) - { - throw PSTraceSource.NewArgumentNullException(nameof(instance)); - } - - // Get owner - try - { - IdentityReference ir = sd.GetOwner(typeof(NTAccount)); - return ir.ToString(); - } - catch (IdentityNotMappedException) - { - // All Acl cmdlets returning SIDs will return a string - // representation of the SID in all cases where the SID - // cannot be mapped to a proper user or group name. - } - - // We are here since we cannot get IdentityReference from sd.. - // So return sddl.. - return sd.GetSecurityDescriptorSddlForm(AccessControlSections.Owner); - } - - /// - /// Gets the Group of the provided PSObject. - /// - /// - /// The PSObject for which to obtain the Group. - /// - /// - /// The Group of the provided PSObject. - /// - public static string GetGroup(PSObject instance) - { - if (instance == null) - { - throw PSTraceSource.NewArgumentNullException(nameof(instance)); - } - - if (!(instance.BaseObject is ObjectSecurity sd)) - { - throw PSTraceSource.NewArgumentNullException(nameof(instance)); - } - - // Get Group - try - { - IdentityReference ir = sd.GetGroup(typeof(NTAccount)); - return ir.ToString(); - } - catch (IdentityNotMappedException) - { - // All Acl cmdlets returning SIDs will return a string - // representation of the SID in all cases where the SID - // cannot be mapped to a proper user or group name. - } - - // We are here since we cannot get IdentityReference from sd.. - // So return sddl.. - return sd.GetSecurityDescriptorSddlForm(AccessControlSections.Group); - } - /// - /// Gets the access rules of the provided PSObject. - /// - /// - /// The PSObject for which to obtain the access rules. - /// - /// - /// The access rules of the provided PSObject. - /// - public static AuthorizationRuleCollection GetAccess(PSObject instance) - { - if (instance == null) - { - throw PSTraceSource.NewArgumentNullException(nameof(instance)); - } - - ObjectSecurity sd = instance.BaseObject as ObjectSecurity; - if (sd == null) - { - PSTraceSource.NewArgumentException(nameof(instance)); - } - - // Get DACL - CommonObjectSecurity cos = sd as CommonObjectSecurity; - if (cos != null) - { - return cos.GetAccessRules(true, true, typeof(NTAccount)); - } - else - { - DirectoryObjectSecurity dos = sd as DirectoryObjectSecurity; - Dbg.Diagnostics.Assert(dos != null, "Acl should be of type CommonObjectSecurity or DirectoryObjectSecurity"); - return dos.GetAccessRules(true, true, typeof(NTAccount)); - } - } - - /// - /// Gets the audit rules of the provided PSObject. - /// - /// - /// The PSObject for which to obtain the audit rules. - /// - /// - /// The audit rules of the provided PSObject. - /// - public static AuthorizationRuleCollection GetAudit(PSObject instance) - { - if (instance == null) - { - throw PSTraceSource.NewArgumentNullException(nameof(instance)); - } - - ObjectSecurity sd = instance.BaseObject as ObjectSecurity; - if (sd == null) - { - PSTraceSource.NewArgumentException(nameof(instance)); - } - - CommonObjectSecurity cos = sd as CommonObjectSecurity; - if (cos != null) - { - return cos.GetAuditRules(true, true, typeof(NTAccount)); - } - else - { - DirectoryObjectSecurity dos = sd as DirectoryObjectSecurity; - Dbg.Diagnostics.Assert(dos != null, "Acl should be of type CommonObjectSecurity or DirectoryObjectSecurity"); - return dos.GetAuditRules(true, true, typeof(NTAccount)); - } - } - - /// - /// Gets the central access policy ID of the provided PSObject. - /// - /// - /// The PSObject for which to obtain the central access policy ID. - /// - /// - /// The central access policy ID of the provided PSObject. - /// - public static SecurityIdentifier GetCentralAccessPolicyId(PSObject instance) - { - SessionState sessionState = new(); - string path = sessionState.Path.GetUnresolvedProviderPathFromPSPath( - GetPath(instance)); - IntPtr pSd = IntPtr.Zero; - - try - { - // Get the file's SACL containing the CAPID ACE. - uint rs = NativeMethods.GetNamedSecurityInfo( - path, - NativeMethods.SeObjectType.SE_FILE_OBJECT, - NativeMethods.SecurityInformation.SCOPE_SECURITY_INFORMATION, - out IntPtr pOwner, - out IntPtr pGroup, - out IntPtr pDacl, - out IntPtr pSacl, - out pSd); - if (rs != NativeMethods.ERROR_SUCCESS) - { - throw new Win32Exception((int)rs); - } - - if (pSacl == IntPtr.Zero) - { - return null; - } - - NativeMethods.ACL sacl = Marshal.PtrToStructure(pSacl); - if (sacl.AceCount == 0) - { - return null; - } - - // Extract the first CAPID from the SACL that does not have INHERIT_ONLY_ACE flag set. - IntPtr pAce = pSacl + Marshal.SizeOf(new NativeMethods.ACL()); - for (ushort aceIdx = 0; aceIdx < sacl.AceCount; aceIdx++) - { - NativeMethods.ACE_HEADER ace = Marshal.PtrToStructure(pAce); - Dbg.Diagnostics.Assert(ace.AceType == - NativeMethods.SYSTEM_SCOPED_POLICY_ID_ACE_TYPE, - "Unexpected ACE type: " + ace.AceType.ToString(CultureInfo.CurrentCulture)); - if ((ace.AceFlags & NativeMethods.INHERIT_ONLY_ACE) == 0) - { - break; - } - - pAce += ace.AceSize; - } - - IntPtr pSid = pAce + Marshal.SizeOf(new NativeMethods.SYSTEM_AUDIT_ACE()) - - Marshal.SizeOf(new uint()); - bool ret = NativeMethods.IsValidSid(pSid); - if (!ret) - { - throw new Win32Exception(Marshal.GetLastWin32Error()); - } - - return new SecurityIdentifier(pSid); - } - finally - { - NativeMethods.LocalFree(pSd); - } - } - -#if !CORECLR - /// - /// Gets the central access policy name of the provided PSObject. - /// - /// - /// Function 'LsaQueryCAPs' is not available in OneCoreUAP and NanoServer. - /// - /// - /// The PSObject for which to obtain the central access policy name. - /// - /// - /// The central access policy name of the provided PSObject. - /// - public static string GetCentralAccessPolicyName(PSObject instance) - { - SecurityIdentifier capId = GetCentralAccessPolicyId(instance); - if (capId == null) - { - return null; // file does not have the scope ace - } - - int capIdSize = capId.BinaryLength; - byte[] capIdArray = new byte[capIdSize]; - capId.GetBinaryForm(capIdArray, 0); - IntPtr caps = IntPtr.Zero; - IntPtr pCapId = Marshal.AllocHGlobal(capIdSize); - - try - { - // Retrieve the CAP by CAPID. - Marshal.Copy(capIdArray, 0, pCapId, capIdSize); - IntPtr[] ppCapId = new IntPtr[1]; - ppCapId[0] = pCapId; - uint rs = NativeMethods.LsaQueryCAPs( - ppCapId, - 1, - out caps, - out uint capCount); - if (rs != NativeMethods.STATUS_SUCCESS) - { - throw new Win32Exception((int)rs); - } - - if (capCount == 0 || caps == IntPtr.Zero) - { - return null; - } - - // Get the CAP name. - NativeMethods.CENTRAL_ACCESS_POLICY cap = Marshal.PtrToStructure(caps); - // LSA_UNICODE_STRING is composed of WCHARs, but its length is given in bytes. - return Marshal.PtrToStringUni(cap.Name.Buffer, cap.Name.Length / 2); - } - finally - { - Marshal.FreeHGlobal(pCapId); - uint rs = NativeMethods.LsaFreeMemory(caps); - Dbg.Diagnostics.Assert(rs == NativeMethods.STATUS_SUCCESS, - "LsaFreeMemory failed: " + rs.ToString(CultureInfo.CurrentCulture)); - } - } - - /// - /// Gets the names and IDs of all central access policies available on the machine. - /// - /// - /// Function 'LsaQueryCAPs' is not available in OneCoreUAP and NanoServer. - /// - /// - /// The PSObject argument is ignored. - /// - /// - /// The names and IDs of all central access policies available on the machine. - /// - public static string[] GetAllCentralAccessPolicies(PSObject instance) - { - IntPtr caps = IntPtr.Zero; - - try - { - // Retrieve all CAPs. - uint rs = NativeMethods.LsaQueryCAPs( - null, - 0, - out caps, - out uint capCount); - if (rs != NativeMethods.STATUS_SUCCESS) - { - throw new Win32Exception((int)rs); - } - - Dbg.Diagnostics.Assert(capCount < 0xFFFF, - "Too many central access policies"); - if (capCount == 0 || caps == IntPtr.Zero) - { - return null; - } - - // Add CAP names and IDs to a string array. - string[] policies = new string[capCount]; - IntPtr capPtr = caps; - for (uint capIdx = 0; capIdx < capCount; capIdx++) - { - // Retrieve CAP name. - Dbg.Diagnostics.Assert(capPtr != IntPtr.Zero, - "Invalid central access policies array"); - NativeMethods.CENTRAL_ACCESS_POLICY cap = Marshal.PtrToStructure(capPtr); - // LSA_UNICODE_STRING is composed of WCHARs, but its length is given in bytes. - policies[capIdx] = "\"" + Marshal.PtrToStringUni( - cap.Name.Buffer, - cap.Name.Length / 2) + "\""; - - // Retrieve CAPID. - IntPtr pCapId = cap.CAPID; - Dbg.Diagnostics.Assert(pCapId != IntPtr.Zero, - "Invalid central access policies array"); - bool ret = NativeMethods.IsValidSid(pCapId); - if (!ret) - { - throw new Win32Exception(Marshal.GetLastWin32Error()); - } - - SecurityIdentifier sid = new SecurityIdentifier(pCapId); - policies[capIdx] += " (" + sid.ToString() + ")"; - - capPtr += Marshal.SizeOf(cap); - } - - return policies; - } - finally - { - uint rs = NativeMethods.LsaFreeMemory(caps); - Dbg.Diagnostics.Assert(rs == NativeMethods.STATUS_SUCCESS, - "LsaFreeMemory failed: " + rs.ToString(CultureInfo.CurrentCulture)); - } - } -#endif - - /// - /// Gets the security descriptor (in SDDL form) of the - /// provided PSObject. SDDL form is the Security Descriptor - /// Definition Language. - /// - /// - /// The PSObject for which to obtain the security descriptor. - /// - /// - /// The security descriptor of the provided PSObject, in SDDL form. - /// - public static string GetSddl(PSObject instance) - { - if (instance == null) - { - throw PSTraceSource.NewArgumentNullException(nameof(instance)); - } - - if (!(instance.BaseObject is ObjectSecurity sd)) - { - throw PSTraceSource.NewArgumentNullException(nameof(instance)); - } - - string sddl = sd.GetSecurityDescriptorSddlForm(AccessControlSections.All); - return sddl; - } - - #endregion brokered properties - /// /// The filter to be used to when globbing to get the item. /// diff --git a/src/System.Management.Automation/engine/InitialSessionState.cs b/src/System.Management.Automation/engine/InitialSessionState.cs index 05eb871053d..cf3d208cb08 100644 --- a/src/System.Management.Automation/engine/InitialSessionState.cs +++ b/src/System.Management.Automation/engine/InitialSessionState.cs @@ -3929,13 +3929,6 @@ internal PSSnapInInfo ImportPSSnapIn(PSSnapInInfo psSnapInInfo, out PSSnapInExce this.Assemblies.Add(assemblyEntry); - // entry from types.ps1xml references a type (Microsoft.PowerShell.Commands.SecurityDescriptorCommandsBase) in this assembly - if (psSnapInInfo.Name.Equals(CoreSnapin, StringComparison.OrdinalIgnoreCase)) - { - assemblyEntry = new SessionStateAssemblyEntry("Microsoft.PowerShell.Security", null); - this.Assemblies.Add(assemblyEntry); - } - if (cmdlets != null) { foreach (SessionStateCmdletEntry cmdlet in cmdlets.Values) diff --git a/src/System.Management.Automation/engine/SecurityDescriptorCommandsHelperBase.cs b/src/System.Management.Automation/engine/SecurityDescriptorCommandsHelperBase.cs new file mode 100644 index 00000000000..540eb31e74c --- /dev/null +++ b/src/System.Management.Automation/engine/SecurityDescriptorCommandsHelperBase.cs @@ -0,0 +1,502 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#nullable enable + +using System; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Globalization; +using System.Management.Automation; +using System.Management.Automation.Security; +using System.Runtime.InteropServices; +using System.Security.AccessControl; +using System.Security.Principal; + +using Dbg = System.Management.Automation; + +namespace Microsoft.PowerShell.Commands.Internal +{ + /// + /// Defines the base class from which all Security Descriptor commands + /// are derived. + /// + public abstract class SecurityDescriptorCommandsHelperBase : PSCmdlet + { + #region brokered properties + + /// + /// Add brokered properties for easy access to important properties + /// of security descriptor. + /// + internal static void AddBrokeredProperties( + Collection results, + bool audit, + bool allCentralAccessPolicies) + { + foreach (PSObject result in results) + { + if (audit) + { + // Audit + result.Properties.Add + ( + new PSCodeProperty + ( + "Audit", + typeof(SecurityDescriptorCommandsHelperBase).GetMethod("GetAudit") + ) + ); + } + // CentralAccessPolicyId retrieval does not require elevation, so we always add this property. + result.Properties.Add + ( + new PSCodeProperty + ( + "CentralAccessPolicyId", + typeof(SecurityDescriptorCommandsHelperBase).GetMethod("GetCentralAccessPolicyId") + ) + ); +#if !CORECLR // GetAllCentralAccessPolicies and GetCentralAccessPolicyName are not supported in OneCore powershell + // because function 'LsaQueryCAPs' is not available in OneCoreUAP and NanoServer. + if (allCentralAccessPolicies) + { + // AllCentralAccessPolicies + result.Properties.Add + ( + new PSCodeProperty + ( + "AllCentralAccessPolicies", + typeof(SecurityDescriptorCommandsHelperBase).GetMethod("GetAllCentralAccessPolicies") + ) + ); + } + // CentralAccessPolicyName retrieval does not require elevation, so we always add this property. + result.Properties.Add + ( + new PSCodeProperty + ( + "CentralAccessPolicyName", + typeof(SecurityDescriptorCommandsHelperBase).GetMethod("GetCentralAccessPolicyName") + ) + ); +#endif + } + } + + /// + /// Gets the Path of the provided PSObject. + /// + /// + /// The PSObject for which to obtain the path. + /// + /// + /// The path of the provided PSObject. + /// + public static string GetPath(PSObject instance) + { + if (instance == null) + { + throw PSTraceSource.NewArgumentNullException(nameof(instance)); + } + else + { + // These are guaranteed to not be null + // Get path + return instance.Properties["PSPath"].Value.ToString()!; + } + } + + /// + /// Gets the Owner of the provided PSObject. + /// + /// + /// The PSObject for which to obtain the Owner. + /// + /// + /// The Owner of the provided PSObject. + /// + public static string? GetOwner(PSObject instance) + { + if (instance == null) + { + throw PSTraceSource.NewArgumentNullException(nameof(instance)); + } + + if (!(instance.BaseObject is ObjectSecurity sd)) + { + throw PSTraceSource.NewArgumentNullException(nameof(instance)); + } + + // Get owner + try + { + IdentityReference? ir = sd.GetOwner(typeof(NTAccount)); + return ir?.ToString(); + } + catch (IdentityNotMappedException) + { + // All Acl cmdlets returning SIDs will return a string + // representation of the SID in all cases where the SID + // cannot be mapped to a proper user or group name. + } + + // We are here since we cannot get IdentityReference from sd.. + // So return sddl.. + return sd.GetSecurityDescriptorSddlForm(AccessControlSections.Owner); + } + + /// + /// Gets the Group of the provided PSObject. + /// + /// + /// The PSObject for which to obtain the Group. + /// + /// + /// The Group of the provided PSObject. + /// + public static string? GetGroup(PSObject instance) + { + if (instance == null) + { + throw PSTraceSource.NewArgumentNullException(nameof(instance)); + } + + if (!(instance.BaseObject is ObjectSecurity sd)) + { + throw PSTraceSource.NewArgumentNullException(nameof(instance)); + } + + // Get Group + try + { + IdentityReference? ir = sd.GetGroup(typeof(NTAccount)); + return ir?.ToString(); + } + catch (IdentityNotMappedException) + { + // All Acl cmdlets returning SIDs will return a string + // representation of the SID in all cases where the SID + // cannot be mapped to a proper user or group name. + } + + // We are here since we cannot get IdentityReference from sd.. + // So return sddl.. + return sd.GetSecurityDescriptorSddlForm(AccessControlSections.Group); + } + /// + /// Gets the access rules of the provided PSObject. + /// + /// + /// The PSObject for which to obtain the access rules. + /// + /// + /// The access rules of the provided PSObject. + /// + public static AuthorizationRuleCollection GetAccess(PSObject instance) + { + if (instance == null) + { + throw PSTraceSource.NewArgumentNullException(nameof(instance)); + } + + ObjectSecurity? sd = instance.BaseObject as ObjectSecurity; + if (sd == null) + { + PSTraceSource.NewArgumentException(nameof(instance)); + } + + // Get DACL + CommonObjectSecurity? cos = sd as CommonObjectSecurity; + if (cos != null) + { + return cos.GetAccessRules(true, true, typeof(NTAccount)); + } + else + { + DirectoryObjectSecurity? dos = sd as DirectoryObjectSecurity; + Dbg.Diagnostics.Assert(dos != null, "Acl should be of type CommonObjectSecurity or DirectoryObjectSecurity"); + return dos.GetAccessRules(true, true, typeof(NTAccount)); + } + } + + /// + /// Gets the audit rules of the provided PSObject. + /// + /// + /// The PSObject for which to obtain the audit rules. + /// + /// + /// The audit rules of the provided PSObject. + /// + public static AuthorizationRuleCollection GetAudit(PSObject instance) + { + if (instance == null) + { + throw PSTraceSource.NewArgumentNullException(nameof(instance)); + } + + ObjectSecurity? sd = instance.BaseObject as ObjectSecurity; + if (sd == null) + { + PSTraceSource.NewArgumentException(nameof(instance)); + } + + CommonObjectSecurity? cos = sd as CommonObjectSecurity; + if (cos != null) + { + return cos.GetAuditRules(true, true, typeof(NTAccount)); + } + else + { + DirectoryObjectSecurity? dos = sd as DirectoryObjectSecurity; + Dbg.Diagnostics.Assert(dos != null, "Acl should be of type CommonObjectSecurity or DirectoryObjectSecurity"); + return dos.GetAuditRules(true, true, typeof(NTAccount)); + } + } + + /// + /// Gets the central access policy ID of the provided PSObject. + /// + /// + /// The PSObject for which to obtain the central access policy ID. + /// + /// + /// The central access policy ID of the provided PSObject. + /// + public static SecurityIdentifier? GetCentralAccessPolicyId(PSObject instance) + { + SessionState sessionState = new(); + string path = sessionState.Path.GetUnresolvedProviderPathFromPSPath( + GetPath(instance)); + IntPtr pSd = IntPtr.Zero; + + try + { + // Get the file's SACL containing the CAPID ACE. + uint rs = NativeMethods.GetNamedSecurityInfo( + path, + NativeMethods.SeObjectType.SE_FILE_OBJECT, + NativeMethods.SecurityInformation.SCOPE_SECURITY_INFORMATION, + out IntPtr pOwner, + out IntPtr pGroup, + out IntPtr pDacl, + out IntPtr pSacl, + out pSd); + if (rs != NativeMethods.ERROR_SUCCESS) + { + throw new Win32Exception((int)rs); + } + + if (pSacl == IntPtr.Zero) + { + return null; + } + + NativeMethods.ACL sacl = Marshal.PtrToStructure(pSacl); + if (sacl.AceCount == 0) + { + return null; + } + + // Extract the first CAPID from the SACL that does not have INHERIT_ONLY_ACE flag set. + IntPtr pAce = pSacl + Marshal.SizeOf(new NativeMethods.ACL()); + for (ushort aceIdx = 0; aceIdx < sacl.AceCount; aceIdx++) + { + NativeMethods.ACE_HEADER ace = Marshal.PtrToStructure(pAce); + Dbg.Diagnostics.Assert(ace.AceType == + NativeMethods.SYSTEM_SCOPED_POLICY_ID_ACE_TYPE, + "Unexpected ACE type: " + ace.AceType.ToString(CultureInfo.CurrentCulture)); + if ((ace.AceFlags & NativeMethods.INHERIT_ONLY_ACE) == 0) + { + break; + } + + pAce += ace.AceSize; + } + + IntPtr pSid = pAce + Marshal.SizeOf(new NativeMethods.SYSTEM_AUDIT_ACE()) - + Marshal.SizeOf(new uint()); + bool ret = NativeMethods.IsValidSid(pSid); + if (!ret) + { + throw new Win32Exception(Marshal.GetLastWin32Error()); + } + + return new SecurityIdentifier(pSid); + } + finally + { + NativeMethods.LocalFree(pSd); + } + } + +#if !CORECLR + /// + /// Gets the central access policy name of the provided PSObject. + /// + /// + /// Function 'LsaQueryCAPs' is not available in OneCoreUAP and NanoServer. + /// + /// + /// The PSObject for which to obtain the central access policy name. + /// + /// + /// The central access policy name of the provided PSObject. + /// + public static string GetCentralAccessPolicyName(PSObject instance) + { + SecurityIdentifier capId = GetCentralAccessPolicyId(instance); + if (capId == null) + { + return null; // file does not have the scope ace + } + + int capIdSize = capId.BinaryLength; + byte[] capIdArray = new byte[capIdSize]; + capId.GetBinaryForm(capIdArray, 0); + IntPtr caps = IntPtr.Zero; + IntPtr pCapId = Marshal.AllocHGlobal(capIdSize); + + try + { + // Retrieve the CAP by CAPID. + Marshal.Copy(capIdArray, 0, pCapId, capIdSize); + IntPtr[] ppCapId = new IntPtr[1]; + ppCapId[0] = pCapId; + uint rs = NativeMethods.LsaQueryCAPs( + ppCapId, + 1, + out caps, + out uint capCount); + if (rs != NativeMethods.STATUS_SUCCESS) + { + throw new Win32Exception((int)rs); + } + + if (capCount == 0 || caps == IntPtr.Zero) + { + return null; + } + + // Get the CAP name. + NativeMethods.CENTRAL_ACCESS_POLICY cap = Marshal.PtrToStructure(caps); + // LSA_UNICODE_STRING is composed of WCHARs, but its length is given in bytes. + return Marshal.PtrToStringUni(cap.Name.Buffer, cap.Name.Length / 2); + } + finally + { + Marshal.FreeHGlobal(pCapId); + uint rs = NativeMethods.LsaFreeMemory(caps); + Dbg.Diagnostics.Assert(rs == NativeMethods.STATUS_SUCCESS, + "LsaFreeMemory failed: " + rs.ToString(CultureInfo.CurrentCulture)); + } + } + + /// + /// Gets the names and IDs of all central access policies available on the machine. + /// + /// + /// Function 'LsaQueryCAPs' is not available in OneCoreUAP and NanoServer. + /// + /// + /// The PSObject argument is ignored. + /// + /// + /// The names and IDs of all central access policies available on the machine. + /// + public static string[] GetAllCentralAccessPolicies(PSObject instance) + { + IntPtr caps = IntPtr.Zero; + + try + { + // Retrieve all CAPs. + uint rs = NativeMethods.LsaQueryCAPs( + null, + 0, + out caps, + out uint capCount); + if (rs != NativeMethods.STATUS_SUCCESS) + { + throw new Win32Exception((int)rs); + } + + Dbg.Diagnostics.Assert(capCount < 0xFFFF, + "Too many central access policies"); + if (capCount == 0 || caps == IntPtr.Zero) + { + return null; + } + + // Add CAP names and IDs to a string array. + string[] policies = new string[capCount]; + IntPtr capPtr = caps; + for (uint capIdx = 0; capIdx < capCount; capIdx++) + { + // Retrieve CAP name. + Dbg.Diagnostics.Assert(capPtr != IntPtr.Zero, + "Invalid central access policies array"); + NativeMethods.CENTRAL_ACCESS_POLICY cap = Marshal.PtrToStructure(capPtr); + // LSA_UNICODE_STRING is composed of WCHARs, but its length is given in bytes. + policies[capIdx] = "\"" + Marshal.PtrToStringUni( + cap.Name.Buffer, + cap.Name.Length / 2) + "\""; + + // Retrieve CAPID. + IntPtr pCapId = cap.CAPID; + Dbg.Diagnostics.Assert(pCapId != IntPtr.Zero, + "Invalid central access policies array"); + bool ret = NativeMethods.IsValidSid(pCapId); + if (!ret) + { + throw new Win32Exception(Marshal.GetLastWin32Error()); + } + + SecurityIdentifier sid = new SecurityIdentifier(pCapId); + policies[capIdx] += " (" + sid.ToString() + ")"; + + capPtr += Marshal.SizeOf(cap); + } + + return policies; + } + finally + { + uint rs = NativeMethods.LsaFreeMemory(caps); + Dbg.Diagnostics.Assert(rs == NativeMethods.STATUS_SUCCESS, + "LsaFreeMemory failed: " + rs.ToString(CultureInfo.CurrentCulture)); + } + } +#endif + + /// + /// Gets the security descriptor (in SDDL form) of the + /// provided PSObject. SDDL form is the Security Descriptor + /// Definition Language. + /// + /// + /// The PSObject for which to obtain the security descriptor. + /// + /// + /// The security descriptor of the provided PSObject, in SDDL form. + /// + public static string GetSddl(PSObject instance) + { + if (instance == null) + { + throw PSTraceSource.NewArgumentNullException(nameof(instance)); + } + + if (!(instance.BaseObject is ObjectSecurity sd)) + { + throw PSTraceSource.NewArgumentNullException(nameof(instance)); + } + + string sddl = sd.GetSecurityDescriptorSddlForm(AccessControlSections.All); + return sddl; + } + + #endregion brokered properties + } +} diff --git a/src/System.Management.Automation/engine/TypeTable_Types_Ps1Xml.cs b/src/System.Management.Automation/engine/TypeTable_Types_Ps1Xml.cs index 648bafe152c..6f2b21e960c 100644 --- a/src/System.Management.Automation/engine/TypeTable_Types_Ps1Xml.cs +++ b/src/System.Management.Automation/engine/TypeTable_Types_Ps1Xml.cs @@ -7,6 +7,8 @@ using System.Reflection; using System.Threading; +using Microsoft.PowerShell.Commands.Internal; + namespace System.Management.Automation.Runspaces { public sealed partial class TypeTable @@ -4063,7 +4065,6 @@ private void Process_Types_Ps1Xml(string filePath, ConcurrentBag errors) typeName = @"System.Security.AccessControl.ObjectSecurity"; typeMembers = _extendedMembers.GetOrAdd(typeName, static key => new PSMemberInfoInternalCollection(capacity: 7)); - Type securityDescriptorCommandsBaseType = TypeResolver.ResolveType("Microsoft.PowerShell.Commands.SecurityDescriptorCommandsBase", exception: out _); // Process regular members. newMembers.Add(@"Path"); @@ -4072,7 +4073,7 @@ private void Process_Types_Ps1Xml(string filePath, ConcurrentBag errors) typeName, new PSCodeProperty( @"Path", - GetMethodInfo(securityDescriptorCommandsBaseType, @"GetPath"), + GetMethodInfo(typeof(SecurityDescriptorCommandsHelperBase), @"GetPath"), setterCodeReference: null), typeMembers, isOverride: false); @@ -4083,7 +4084,7 @@ private void Process_Types_Ps1Xml(string filePath, ConcurrentBag errors) typeName, new PSCodeProperty( @"Owner", - GetMethodInfo(securityDescriptorCommandsBaseType, @"GetOwner"), + GetMethodInfo(typeof(SecurityDescriptorCommandsHelperBase), @"GetOwner"), setterCodeReference: null), typeMembers, isOverride: false); @@ -4094,7 +4095,7 @@ private void Process_Types_Ps1Xml(string filePath, ConcurrentBag errors) typeName, new PSCodeProperty( @"Group", - GetMethodInfo(securityDescriptorCommandsBaseType, @"GetGroup"), + GetMethodInfo(typeof(SecurityDescriptorCommandsHelperBase), @"GetGroup"), setterCodeReference: null), typeMembers, isOverride: false); @@ -4105,7 +4106,7 @@ private void Process_Types_Ps1Xml(string filePath, ConcurrentBag errors) typeName, new PSCodeProperty( @"Access", - GetMethodInfo(securityDescriptorCommandsBaseType, @"GetAccess"), + GetMethodInfo(typeof(SecurityDescriptorCommandsHelperBase), @"GetAccess"), setterCodeReference: null), typeMembers, isOverride: false); @@ -4116,7 +4117,7 @@ private void Process_Types_Ps1Xml(string filePath, ConcurrentBag errors) typeName, new PSCodeProperty( @"Sddl", - GetMethodInfo(securityDescriptorCommandsBaseType, @"GetSddl"), + GetMethodInfo(typeof(SecurityDescriptorCommandsHelperBase), @"GetSddl"), setterCodeReference: null), typeMembers, isOverride: false); From 492f2e1cc18d4aa05ef4c028806cb385135c1496 Mon Sep 17 00:00:00 2001 From: Ilya Date: Mon, 1 Nov 2021 22:44:08 +0500 Subject: [PATCH 2/2] Fix test --- test/powershell/Host/Startup.Tests.ps1 | 1 - 1 file changed, 1 deletion(-) diff --git a/test/powershell/Host/Startup.Tests.ps1 b/test/powershell/Host/Startup.Tests.ps1 index bb775d0ca2f..c2b62df5686 100644 --- a/test/powershell/Host/Startup.Tests.ps1 +++ b/test/powershell/Host/Startup.Tests.ps1 @@ -7,7 +7,6 @@ Describe "Validate start of console host" -Tag CI { 'Microsoft.ApplicationInsights.dll' 'Microsoft.Management.Infrastructure.dll' 'Microsoft.PowerShell.ConsoleHost.dll' - 'Microsoft.PowerShell.Security.dll' 'Microsoft.Win32.Primitives.dll' 'Microsoft.Win32.Registry.dll' 'netstandard.dll'