/// <summary> /// Gets the SecurityDescriptor at the specified path, including only the specified /// AccessControlSections. /// </summary> /// /// <param name="path"> /// The path of the item to retrieve. It may be a drive or provider-qualified path and may include. /// glob characters. /// </param> /// /// <param name="sections"> /// The sections of the security descriptor to include. /// </param> /// /// <returns> /// Nothing. An object that represents the security descriptor for the item /// specified by path is written to the context's pipeline. /// </returns> /// /// <exception cref="System.ArgumentException"> /// path is null or empty. /// path doesn't exist /// sections is not valid. /// </exception> public void GetSecurityDescriptor(string path, AccessControlSections sections) { ObjectSecurity sd = null; path = NormalizePath(path); if (String.IsNullOrEmpty(path)) { throw PSTraceSource.NewArgumentNullException("path"); } if ((sections & ~AccessControlSections.All) != 0) { throw PSTraceSource.NewArgumentException("sections"); } var currentPrivilegeState = new PlatformInvokes.TOKEN_PRIVILEGE(); try { PlatformInvokes.EnableTokenPrivilege("SeBackupPrivilege", ref currentPrivilegeState); if (Directory.Exists(path)) { sd = new DirectorySecurity(path, sections); } else { sd = new FileSecurity(path, sections); } } catch (System.Security.SecurityException e) { WriteError(new ErrorRecord(e, e.GetType().FullName, ErrorCategory.PermissionDenied, path)); } finally { PlatformInvokes.RestoreTokenPrivilege("SeBackupPrivilege", ref currentPrivilegeState); } WriteSecurityDescriptorObject(sd, path); }
/// <summary> /// Do the actual connection to remote machine for Invoke-WMIMethod cmdlet and raise operation complete event. /// </summary> private void ConnectInvokeWmi() { InvokeWmiMethod invokeObject = (InvokeWmiMethod)_wmiObject; _state = WmiState.Running; RaiseWmiOperationState(null, WmiState.Running); if (invokeObject.InputObject != null) { ManagementBaseObject inputParameters = null; try { inputParameters = invokeObject.InputObject.GetMethodParameters(invokeObject.Name); if (invokeObject.ArgumentList != null) { int inParamCount = invokeObject.ArgumentList.Length; foreach (PropertyData property in inputParameters.Properties) { if (inParamCount == 0) break; property.Value = invokeObject.ArgumentList[invokeObject.ArgumentList.Length - inParamCount]; inParamCount--; } } invokeObject.InputObject.InvokeMethod(_results, invokeObject.Name, inputParameters, null); } catch (ManagementException e) { internalException = e; _state = WmiState.Failed; RaiseOperationCompleteEvent(null, OperationState.StopComplete); } catch (System.Runtime.InteropServices.COMException e) { internalException = e; _state = WmiState.Failed; RaiseOperationCompleteEvent(null, OperationState.StopComplete); } catch (System.UnauthorizedAccessException e) { internalException = e; _state = WmiState.Failed; RaiseOperationCompleteEvent(null, OperationState.StopComplete); } return; } else { ConnectionOptions options = invokeObject.GetConnectionOption(); ManagementPath mPath = null; ManagementObject mObject = null; if (invokeObject.Path != null) { mPath = new ManagementPath(invokeObject.Path); if (String.IsNullOrEmpty(mPath.NamespacePath)) { mPath.NamespacePath = invokeObject.Namespace; } else if (invokeObject.namespaceSpecified) { InvalidOperationException e = new InvalidOperationException("NamespaceSpecifiedWithPath"); internalException = e; _state = WmiState.Failed; RaiseOperationCompleteEvent(null, OperationState.StopComplete); return; } if (mPath.Server != "." && invokeObject.serverNameSpecified) { InvalidOperationException e = new InvalidOperationException("ComputerNameSpecifiedWithPath"); internalException = e; _state = WmiState.Failed; RaiseOperationCompleteEvent(null, OperationState.StopComplete); return; } //If server name is specified loop through it. if (!(mPath.Server == "." && invokeObject.serverNameSpecified)) { _computerName = mPath.Server; } } bool isLocal = false, needToEnablePrivilege = false; PlatformInvokes.TOKEN_PRIVILEGE currentPrivilegeState = new PlatformInvokes.TOKEN_PRIVILEGE(); try { needToEnablePrivilege = NeedToEnablePrivilege(_computerName, invokeObject.Name, ref isLocal); if (needToEnablePrivilege) { if (!(isLocal && PlatformInvokes.EnableTokenPrivilege(ComputerWMIHelper.SE_SHUTDOWN_NAME, ref currentPrivilegeState)) && !(!isLocal && PlatformInvokes.EnableTokenPrivilege(ComputerWMIHelper.SE_REMOTE_SHUTDOWN_NAME, ref currentPrivilegeState))) { string message = StringUtil.Format(ComputerResources.PrivilegeNotEnabled, _computerName, isLocal ? ComputerWMIHelper.SE_SHUTDOWN_NAME : ComputerWMIHelper.SE_REMOTE_SHUTDOWN_NAME); InvalidOperationException e = new InvalidOperationException(message); internalException = e; _state = WmiState.Failed; RaiseOperationCompleteEvent(null, OperationState.StopComplete); return; } } if (invokeObject.Path != null) { mPath.Server = _computerName; if (mPath.IsClass) { ManagementClass mClass = new ManagementClass(mPath); mObject = mClass; } else { ManagementObject mInstance = new ManagementObject(mPath); mObject = mInstance; } ManagementScope mScope = new ManagementScope(mPath, options); mObject.Scope = mScope; } else { ManagementScope scope = new ManagementScope(WMIHelper.GetScopeString(_computerName, invokeObject.Namespace), options); ManagementClass mClass = new ManagementClass(invokeObject.Class); mObject = mClass; mObject.Scope = scope; } ManagementBaseObject inputParameters = mObject.GetMethodParameters(invokeObject.Name); if (invokeObject.ArgumentList != null) { int inParamCount = invokeObject.ArgumentList.Length; foreach (PropertyData property in inputParameters.Properties) { if (inParamCount == 0) break; property.Value = invokeObject.ArgumentList[invokeObject.ArgumentList.Length - inParamCount]; inParamCount--; } } if (needToEnablePrivilege) { ManagementBaseObject result = mObject.InvokeMethod(invokeObject.Name, inputParameters, null); Dbg.Diagnostics.Assert(result != null, "result cannot be null if the Join method is invoked"); int returnCode = Convert.ToInt32(result["ReturnValue"], CultureInfo.CurrentCulture); if (returnCode != 0) { var e = new Win32Exception(returnCode); internalException = e; _state = WmiState.Failed; RaiseOperationCompleteEvent(null, OperationState.StopComplete); } else { ShutdownComplete.SafeInvoke(this, null); } } else { mObject.InvokeMethod(_results, invokeObject.Name, inputParameters, null); } } catch (ManagementException e) { internalException = e; _state = WmiState.Failed; RaiseOperationCompleteEvent(null, OperationState.StopComplete); } catch (System.Runtime.InteropServices.COMException e) { internalException = e; _state = WmiState.Failed; RaiseOperationCompleteEvent(null, OperationState.StopComplete); } catch (System.UnauthorizedAccessException e) { internalException = e; _state = WmiState.Failed; RaiseOperationCompleteEvent(null, OperationState.StopComplete); } finally { // Restore the previous privilege state if something unexpected happened if (needToEnablePrivilege) { PlatformInvokes.RestoreTokenPrivilege( isLocal ? ComputerWMIHelper.SE_SHUTDOWN_NAME : ComputerWMIHelper.SE_REMOTE_SHUTDOWN_NAME, ref currentPrivilegeState); } } } }
/// <summary> /// Invokes the Win32Shutdown command on provided target computer using WSMan /// over a CIMSession. The flags parameter determines the type of shutdown operation /// such as shutdown, reboot, force etc. /// </summary> /// <param name="cmdlet">Cmdlet host for reporting errors</param> /// <param name="isLocalhost">True if local host computer</param> /// <param name="computerName">Target computer</param> /// <param name="flags">Win32Shutdown flags</param> /// <param name="credential">Optional credential</param> /// <param name="authentication">Optional authentication</param> /// <param name="formatErrorMessage">Error message format string that takes two parameters</param> /// <param name="ErrorFQEID">Fully qualified error Id</param> /// <param name="cancelToken">Cancel token</param> /// <returns>True on success</returns> internal static bool InvokeWin32ShutdownUsingWsman( PSCmdlet cmdlet, bool isLocalhost, string computerName, object[] flags, PSCredential credential, string authentication, string formatErrorMessage, string ErrorFQEID, CancellationToken cancelToken) { Dbg.Diagnostics.Assert(flags.Length == 2, "Caller need to verify the flags passed in"); bool isSuccess = false; string targetMachine = isLocalhost ? "localhost" : computerName; string authInUse = isLocalhost ? null : authentication; PSCredential credInUse = isLocalhost ? null : credential; var currentPrivilegeState = new PlatformInvokes.TOKEN_PRIVILEGE(); var operationOptions = new CimOperationOptions { Timeout = TimeSpan.FromMilliseconds(10000), CancellationToken = cancelToken, //This prefix works against all versions of the WinRM server stack, both win8 and win7 ResourceUriPrefix = new Uri(ComputerWMIHelper.CimUriPrefix) }; try { if (!(isLocalhost && PlatformInvokes.EnableTokenPrivilege(ComputerWMIHelper.SE_SHUTDOWN_NAME, ref currentPrivilegeState)) && !(!isLocalhost && PlatformInvokes.EnableTokenPrivilege(ComputerWMIHelper.SE_REMOTE_SHUTDOWN_NAME, ref currentPrivilegeState))) { string message = StringUtil.Format(ComputerResources.PrivilegeNotEnabled, computerName, isLocalhost ? ComputerWMIHelper.SE_SHUTDOWN_NAME : ComputerWMIHelper.SE_REMOTE_SHUTDOWN_NAME); ErrorRecord errorRecord = new ErrorRecord(new InvalidOperationException(message), "PrivilegeNotEnabled", ErrorCategory.InvalidOperation, null); cmdlet.WriteError(errorRecord); return false; } using (CimSession cimSession = RemoteDiscoveryHelper.CreateCimSession(targetMachine, credInUse, authInUse, cancelToken, cmdlet)) { var methodParameters = new CimMethodParametersCollection(); methodParameters.Add(CimMethodParameter.Create( "Flags", flags[0], Microsoft.Management.Infrastructure.CimType.SInt32, CimFlags.None)); methodParameters.Add(CimMethodParameter.Create( "Reserved", flags[1], Microsoft.Management.Infrastructure.CimType.SInt32, CimFlags.None)); CimMethodResult result = cimSession.InvokeMethod( ComputerWMIHelper.CimOperatingSystemNamespace, ComputerWMIHelper.WMI_Class_OperatingSystem, ComputerWMIHelper.CimOperatingSystemShutdownMethod, methodParameters, operationOptions); int retVal = Convert.ToInt32(result.ReturnValue.Value, CultureInfo.CurrentCulture); if (retVal != 0) { var ex = new Win32Exception(retVal); string errMsg = StringUtil.Format(formatErrorMessage, computerName, ex.Message); ErrorRecord error = new ErrorRecord( new InvalidOperationException(errMsg), ErrorFQEID, ErrorCategory.OperationStopped, computerName); cmdlet.WriteError(error); } else { isSuccess = true; } } } catch (CimException ex) { string errMsg = StringUtil.Format(formatErrorMessage, computerName, ex.Message); ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), ErrorFQEID, ErrorCategory.OperationStopped, computerName); cmdlet.WriteError(error); } catch (Exception ex) { CommandProcessorBase.CheckForSevereException(ex); string errMsg = StringUtil.Format(formatErrorMessage, computerName, ex.Message); ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), ErrorFQEID, ErrorCategory.OperationStopped, computerName); cmdlet.WriteError(error); } finally { // Restore the previous privilege state if something unexpected happened PlatformInvokes.RestoreTokenPrivilege( isLocalhost ? ComputerWMIHelper.SE_SHUTDOWN_NAME : ComputerWMIHelper.SE_REMOTE_SHUTDOWN_NAME, ref currentPrivilegeState); } return isSuccess; }
/// <summary> /// Restart one computer /// </summary> /// <param name="cmdlet"></param> /// <param name="isLocalhost"></param> /// <param name="computerName"></param> /// <param name="flags"></param> /// <param name="options"></param> /// <returns> /// True if the restart was successful /// False otherwise /// </returns> internal static bool RestartOneComputerUsingDcom(PSCmdlet cmdlet, bool isLocalhost, string computerName, object[] flags, ConnectionOptions options) { bool isSuccess = false; PlatformInvokes.TOKEN_PRIVILEGE currentPrivilegeState = new PlatformInvokes.TOKEN_PRIVILEGE(); try { if (!(isLocalhost && PlatformInvokes.EnableTokenPrivilege(ComputerWMIHelper.SE_SHUTDOWN_NAME, ref currentPrivilegeState)) && !(!isLocalhost && PlatformInvokes.EnableTokenPrivilege(ComputerWMIHelper.SE_REMOTE_SHUTDOWN_NAME, ref currentPrivilegeState))) { string message = StringUtil.Format(ComputerResources.PrivilegeNotEnabled, computerName, isLocalhost ? ComputerWMIHelper.SE_SHUTDOWN_NAME : ComputerWMIHelper.SE_REMOTE_SHUTDOWN_NAME); ErrorRecord errorRecord = new ErrorRecord(new InvalidOperationException(message), "PrivilegeNotEnabled", ErrorCategory.InvalidOperation, null); cmdlet.WriteError(errorRecord); return false; } ManagementScope scope = new ManagementScope(ComputerWMIHelper.GetScopeString(isLocalhost ? "localhost" : computerName, ComputerWMIHelper.WMI_Path_CIM), options); EnumerationOptions enumOptions = new EnumerationOptions { UseAmendedQualifiers = true, DirectRead = true }; ObjectQuery query = new ObjectQuery("select * from " + ComputerWMIHelper.WMI_Class_OperatingSystem); using (var searcher = new ManagementObjectSearcher(scope, query, enumOptions)) { foreach (ManagementObject operatingSystem in searcher.Get()) { using (operatingSystem) { object result = operatingSystem.InvokeMethod("Win32shutdown", flags); int retVal = Convert.ToInt32(result.ToString(), CultureInfo.CurrentCulture); if (retVal != 0) { var ex = new Win32Exception(retVal); string errMsg = StringUtil.Format(ComputerResources.RestartcomputerFailed, computerName, ex.Message); ErrorRecord error = new ErrorRecord( new InvalidOperationException(errMsg), "RestartcomputerFailed", ErrorCategory.OperationStopped, computerName); cmdlet.WriteError(error); } else { isSuccess = true; } } } } } catch (ManagementException ex) { string errMsg = StringUtil.Format(ComputerResources.RestartcomputerFailed, computerName, ex.Message); ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "RestartcomputerFailed", ErrorCategory.OperationStopped, computerName); cmdlet.WriteError(error); } catch (COMException ex) { string errMsg = StringUtil.Format(ComputerResources.RestartcomputerFailed, computerName, ex.Message); ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "RestartcomputerFailed", ErrorCategory.OperationStopped, computerName); cmdlet.WriteError(error); } catch (UnauthorizedAccessException ex) { string errMsg = StringUtil.Format(ComputerResources.RestartcomputerFailed, computerName, ex.Message); ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "RestartcomputerFailed", ErrorCategory.OperationStopped, computerName); cmdlet.WriteError(error); } finally { // Restore the previous privilege state if something unexpected happened PlatformInvokes.RestoreTokenPrivilege( isLocalhost ? ComputerWMIHelper.SE_SHUTDOWN_NAME : ComputerWMIHelper.SE_REMOTE_SHUTDOWN_NAME, ref currentPrivilegeState); } return isSuccess; }
} // SetSecurityDescriptor private void SetSecurityDescriptor(string path, ObjectSecurity sd, AccessControlSections sections) { var currentPrivilegeState = new PlatformInvokes.TOKEN_PRIVILEGE(); byte[] securityDescriptorBinary = null; try { // Get the binary form of the descriptor. PlatformInvokes.EnableTokenPrivilege("SeBackupPrivilege", ref currentPrivilegeState); securityDescriptorBinary = sd.GetSecurityDescriptorBinaryForm(); } finally { PlatformInvokes.RestoreTokenPrivilege("SeBackupPrivilege", ref currentPrivilegeState); } try { PlatformInvokes.EnableTokenPrivilege("SeRestorePrivilege", ref currentPrivilegeState); // Transfer it to the new file / directory. // We keep these two code branches so that we can have more // granular information when we ouput the object type via // WriteSecurityDescriptorObject. if (Directory.Exists(path)) { DirectorySecurity newDescriptor = new DirectorySecurity(); newDescriptor.SetSecurityDescriptorBinaryForm(securityDescriptorBinary, sections); new DirectoryInfo(path).SetAccessControl(newDescriptor); WriteSecurityDescriptorObject(newDescriptor, path); } else { FileSecurity newDescriptor = new FileSecurity(); newDescriptor.SetSecurityDescriptorBinaryForm(securityDescriptorBinary, sections); new FileInfo(path).SetAccessControl(newDescriptor); WriteSecurityDescriptorObject(newDescriptor, path); } } finally { PlatformInvokes.RestoreTokenPrivilege("SeRestorePrivilege", ref currentPrivilegeState); } }