From 9f77841ac5a696385d1f388cb438bb7953418f6f Mon Sep 17 00:00:00 2001 From: David Hall Date: Sun, 10 Mar 2019 13:35:42 -0600 Subject: [PATCH] Added impersonated calls - not working --- System/Computer/SharedDevice.cs | 91 +++++++++++++++++++++++------------------ 1 file changed, 52 insertions(+), 39 deletions(-) diff --git a/System/Computer/SharedDevice.cs b/System/Computer/SharedDevice.cs index 50f810a6..ff593db7 100644 --- a/System/Computer/SharedDevice.cs +++ b/System/Computer/SharedDevice.cs @@ -3,7 +3,9 @@ using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Security.AccessControl; +using System.Security.Principal; using Vanara.Extensions; +using Vanara.Security; using static Vanara.PInvoke.NetApi32; namespace Vanara @@ -30,11 +32,13 @@ namespace Vanara /// public class SharedDevice : INamedEntity { + private readonly WindowsIdentity identity; private readonly string target; private STYPE type = (STYPE)uint.MaxValue; - internal SharedDevice(string target, string netname) + internal SharedDevice(string target, string netname, WindowsIdentity accessIdentity) { + identity = accessIdentity; this.target = target; Name = netname; } @@ -43,8 +47,8 @@ namespace Vanara /// The resource description. public string Description { - get => NetShareGetInfo(target, Name).shi1_remark; - set => NetShareSetInfo(target, Name, new SHARE_INFO_1004 { shi1004_remark = value }); + get => GetInfo().shi1_remark; + set => SetInfo(new SHARE_INFO_1004 { shi1004_remark = value }); } /// Gets a value indicating whether this instance is communication device. @@ -82,12 +86,12 @@ namespace Vanara /// The offline settings. public ShareOfflineSettings OfflineSettings { - get => (ShareOfflineSettings)(NetShareGetInfo(target, Name).shi1005_flags & SHI1005_FLAGS.CSC_MASK_EXT); + get => (ShareOfflineSettings)(GetInfo().shi1005_flags & SHI1005_FLAGS.CSC_MASK_EXT); set { - var i = NetShareGetInfo(target, Name); + var i = GetInfo(); i.shi1005_flags = i.shi1005_flags & ~SHI1005_FLAGS.CSC_MASK | (SHI1005_FLAGS)value; - NetShareSetInfo(target, Name, i); + SetInfo(i); } } @@ -102,13 +106,13 @@ namespace Vanara { get { - try { return NetShareGetInfo(target, Name).shi2_path; } catch { return string.Empty; } + try { return GetInfo().shi2_path; } catch { return string.Empty; } } set { - var i = NetShareGetInfo(target, Name); + var i = GetInfo(); i.shi2_path = value; - NetShareSetInfo(target, Name, i); + SetInfo(i); } } @@ -120,13 +124,13 @@ namespace Vanara { get { - try { return NetShareGetInfo(target, Name).shi502_security_descriptor.ToManaged(); } catch { return null; } + try { return GetInfo().shi502_security_descriptor.ToManaged(); } catch { return null; } } set { - var i = NetShareGetInfo(target, Name); + var i = GetInfo(); i.shi502_security_descriptor = value.ToNative(); - NetShareSetInfo(target, Name, i); + SetInfo(i); } } @@ -139,21 +143,21 @@ namespace Vanara { get { - try { return unchecked((int)NetShareGetInfo(target, Name).shi2_max_uses); } catch { return -1; } + try { return unchecked((int)GetInfo().shi2_max_uses); } catch { return -1; } } set { - var i = NetShareGetInfo(target, Name); + var i = GetInfo(); i.shi2_max_uses = unchecked((uint)value); - NetShareSetInfo(target, Name, i); + SetInfo(i); } } /// Gets the shared resource's permissions for servers running with share-level security. /// Returns a value. - private ShareLevelAccess Access => NetShareGetInfo(target, Name).shi2_permissions; + private ShareLevelAccess Access => GetInfo().shi2_permissions; - private STYPE Type => (uint)type == uint.MaxValue ? (type = NetShareGetInfo(target, Name).shi1_type) : type; + private STYPE Type => (uint)type == uint.MaxValue ? type = GetInfo().shi1_type : type; /// Creates the disk volume share. /// @@ -168,39 +172,47 @@ namespace Vanara /// /// On success, a new instance of represented a newly created shared disk. public static SharedDevice CreateDiskVolumeShare(string target, string name, string comment, string path) => - Create(target, name, comment, path, STYPE.STYPE_DISKTREE); + Create(target, name, comment, path, STYPE.STYPE_DISKTREE, null); /// Creates the specified target. - /// - /// A string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. If this parameter is - /// , the local computer is used. - /// + /// A string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. If this parameter is + /// , the local computer is used. /// The share name of a resource. /// An optional comment about the shared resource. - /// - /// The local path for the shared resource. For disks, this is the path being shared. For print queues, this is the name of the print - /// queue being shared. - /// + /// The local path for the shared resource. For disks, this is the path being shared. For print queues, this is the name of the print + /// queue being shared. /// A combination of values that specify the type of the shared resource. - /// On success, a new instance of represented a newly created shared resource. - internal static SharedDevice Create(string target, string name, string comment, string path, STYPE type) + /// The identity. + /// + /// On success, a new instance of represented a newly created shared resource. + /// + internal static SharedDevice Create(string target, string name, string comment, string path, STYPE type, WindowsIdentity identity) { - NetShareAdd(target, new SHARE_INFO_2 { shi2_netname = name, shi2_remark = comment, shi2_path = path, shi2_max_uses = unchecked((uint)-1), shi2_type = type }); - return new SharedDevice(target, name); + identity.Run(() => NetShareAdd(target, new SHARE_INFO_2 { shi2_netname = name, shi2_remark = comment, shi2_path = path, shi2_max_uses = unchecked((uint)-1), shi2_type = type })); + return new SharedDevice(target, name, identity); } + + private T GetInfo() where T : struct => identity.Run(() => NetShareGetInfo(target, Name)); + + private void SetInfo(T s) where T : struct => identity.Run(() => NetShareSetInfo(target, Name, s)); } /// Represents all the shared devices on a computers. - /// public class SharedDevices : Collections.VirtualDictionary { private readonly string target = null; + private readonly WindowsIdentity identity; - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// Name of the computer from which to retrieve and manage the shared devices. - public SharedDevices(string serverName = null) : base(false) => target = serverName; + /// The Windows identity used to access the shared device information. If this value , the current identity is used. + public SharedDevices(string serverName = null, WindowsIdentity accessIdentity = null) : base(false) + { + target = serverName; + identity = accessIdentity; + } - internal SharedDevices(Computer computer) : this(computer.Target) + internal SharedDevices(Computer computer) : this(computer.Target, computer.Identity) { } @@ -211,14 +223,15 @@ namespace Vanara get { var h = 0U; - NetShareEnum(target, 0, out var _, MAX_PREFERRED_LENGTH, out var cnt, out var _, ref h).ThrowIfFailed(); + var cnt = 0U; + identity.Run(() => NetShareEnum(target, 0, out var _, MAX_PREFERRED_LENGTH, out cnt, out _, ref h).ThrowIfFailed()); return (int)cnt; } } /// Gets an containing the keys of the . /// An containing the keys of the object that implements . - public override ICollection Keys => NetShareEnum(target).Select(i => i.shi0_netname).ToArray(); + public override ICollection Keys => identity.Run(() => NetShareEnum(target).Select(i => i.shi0_netname).ToArray()); /// Creates the specified target. /// The share name of a resource. @@ -229,7 +242,7 @@ namespace Vanara /// /// A combination of values that specify the type of the shared resource. /// On success, a new instance of represented a newly created shared resource. - public SharedDevice Add(string name, string comment, string path, STYPE type = STYPE.STYPE_DISKTREE) => SharedDevice.Create(target, name, comment, path, type); + public SharedDevice Add(string name, string comment, string path, STYPE type = STYPE.STYPE_DISKTREE) => SharedDevice.Create(target, name, comment, path, type, identity); /// Removes the element with the specified key from the . /// The key of the element to remove. @@ -237,7 +250,7 @@ namespace Vanara /// if the element is successfully removed; otherwise, . This method also returns false /// if key was not found in the original . /// - public override bool Remove(string key) => NetShareDel(target, key).Succeeded; + public override bool Remove(string key) => identity.Run(() => NetShareDel(target, key).Succeeded); /// Gets the value associated with the specified key. /// The key whose value to get. @@ -251,7 +264,7 @@ namespace Vanara /// public override bool TryGetValue(string key, out SharedDevice value) { - value = ContainsKey(key) ? new SharedDevice(target, key) : null; + value = ContainsKey(key) ? new SharedDevice(target, key, identity) : null; return !(value is null); } }