mirror of https://github.com/dahall/Vanara.git
Cleaned and extended Vanara.Security to support `ActiveDirectoryExtension` on all platforms
parent
9f65b87ab7
commit
9245c5b90e
|
@ -144,7 +144,7 @@ namespace Vanara.Security.AccessControl
|
||||||
/// <returns>An array of <see cref="SecurityIdentifier"/> objects representing all accounts with the specified privilege.</returns>
|
/// <returns>An array of <see cref="SecurityIdentifier"/> objects representing all accounts with the specified privilege.</returns>
|
||||||
public IEnumerable<SecurityIdentifier> EnumerateAccountsWithRight(string privilege)
|
public IEnumerable<SecurityIdentifier> EnumerateAccountsWithRight(string privilege)
|
||||||
{
|
{
|
||||||
var ret = LsaEnumerateAccountsWithUserRight(Handle, privilege, out var buffer, out var count);
|
NTStatus ret = LsaEnumerateAccountsWithUserRight(Handle, privilege, out SafeLsaMemoryHandle buffer, out var count);
|
||||||
if (ret == NTStatus.STATUS_NO_MORE_ENTRIES)
|
if (ret == NTStatus.STATUS_NO_MORE_ENTRIES)
|
||||||
return new SecurityIdentifier[0];
|
return new SecurityIdentifier[0];
|
||||||
ThrowIfLsaError(ret);
|
ThrowIfLsaError(ret);
|
||||||
|
@ -185,11 +185,11 @@ namespace Vanara.Security.AccessControl
|
||||||
{
|
{
|
||||||
if (names == null || names.Length == 0)
|
if (names == null || names.Length == 0)
|
||||||
throw new ArgumentException(@"At least one user name must be supplied.", nameof(names));
|
throw new ArgumentException(@"At least one user name must be supplied.", nameof(names));
|
||||||
var ret = LsaLookupNames2(Handle, localOnly ? LsaLookupNamesFlags.LSA_LOOKUP_ISOLATED_AS_LOCAL : 0, (uint)names.Length, names, out var domains, out var sids);
|
NTStatus ret = LsaLookupNames2(Handle, localOnly ? LsaLookupNamesFlags.LSA_LOOKUP_ISOLATED_AS_LOCAL : 0, (uint)names.Length, names, out SafeLsaMemoryHandle domains, out SafeLsaMemoryHandle sids);
|
||||||
if (ret != NTStatus.STATUS_SUCCESS && ret != NTStatus.STATUS_SOME_NOT_MAPPED)
|
if (ret != NTStatus.STATUS_SUCCESS && ret != NTStatus.STATUS_SOME_NOT_MAPPED)
|
||||||
ThrowIfLsaError(ret);
|
ThrowIfLsaError(ret);
|
||||||
var d = domains.DangerousGetHandle().ToStructure<LSA_REFERENCED_DOMAIN_LIST>().DomainList.ToArray();
|
LSA_TRUST_INFORMATION[] d = domains.DangerousGetHandle().ToStructure<LSA_REFERENCED_DOMAIN_LIST>().DomainList.ToArray();
|
||||||
var ts = sids.DangerousGetHandle().ToIEnum<LSA_TRANSLATED_SID2>(names.Length).ToArray();
|
LSA_TRANSLATED_SID2[] ts = sids.DangerousGetHandle().ToIEnum<LSA_TRANSLATED_SID2>(names.Length).ToArray();
|
||||||
var retVal = new SystemAccountInfo[names.Length];
|
var retVal = new SystemAccountInfo[names.Length];
|
||||||
for (var i = 0; i < names.Length; i++)
|
for (var i = 0; i < names.Length; i++)
|
||||||
retVal[i] = new SystemAccountInfo(names[i], ts[i].Use, IsValidSid(ts[i].Use) ? new SecurityIdentifier((IntPtr)ts[i].Sid) : null, ts[i].DomainIndex, d);
|
retVal[i] = new SystemAccountInfo(names[i], ts[i].Use, IsValidSid(ts[i].Use) ? new SecurityIdentifier((IntPtr)ts[i].Sid) : null, ts[i].DomainIndex, d);
|
||||||
|
@ -206,14 +206,14 @@ namespace Vanara.Security.AccessControl
|
||||||
{
|
{
|
||||||
if (sids == null || sids.Length == 0)
|
if (sids == null || sids.Length == 0)
|
||||||
throw new ArgumentException(@"At least one SecurityIdentifier must be supplied.", nameof(sids));
|
throw new ArgumentException(@"At least one SecurityIdentifier must be supplied.", nameof(sids));
|
||||||
var opts = (preferInternetNames ? LsaLookupSidsFlags.LSA_LOOKUP_PREFER_INTERNET_NAMES : 0) |
|
LsaLookupSidsFlags opts = (preferInternetNames ? LsaLookupSidsFlags.LSA_LOOKUP_PREFER_INTERNET_NAMES : 0) |
|
||||||
(disallowConnectedAccts ? LsaLookupSidsFlags.LSA_LOOKUP_DISALLOW_CONNECTED_ACCOUNT_INTERNET_SID : 0);
|
(disallowConnectedAccts ? LsaLookupSidsFlags.LSA_LOOKUP_DISALLOW_CONNECTED_ACCOUNT_INTERNET_SID : 0);
|
||||||
var psids = sids.Select(s => new PinnedSid(s));
|
IEnumerable<PinnedSid> psids = sids.Select(s => new PinnedSid(s));
|
||||||
var ret = LsaLookupSids2(Handle, opts, (uint)sids.Length, psids.Select(s => s.PSID).ToArray(), out var domains, out var names);
|
NTStatus ret = LsaLookupSids2(Handle, opts, (uint)sids.Length, psids.Select(s => s.PSID).ToArray(), out SafeLsaMemoryHandle domains, out SafeLsaMemoryHandle names);
|
||||||
if (ret != NTStatus.STATUS_SUCCESS && ret != NTStatus.STATUS_SOME_NOT_MAPPED)
|
if (ret != NTStatus.STATUS_SUCCESS && ret != NTStatus.STATUS_SOME_NOT_MAPPED)
|
||||||
ThrowIfLsaError(ret);
|
ThrowIfLsaError(ret);
|
||||||
var d = domains.DangerousGetHandle().ToStructure<LSA_REFERENCED_DOMAIN_LIST>().DomainList.ToArray();
|
LSA_TRUST_INFORMATION[] d = domains.DangerousGetHandle().ToStructure<LSA_REFERENCED_DOMAIN_LIST>().DomainList.ToArray();
|
||||||
var tn = names.DangerousGetHandle().ToIEnum<LSA_TRANSLATED_NAME>(sids.Length).ToArray();
|
LSA_TRANSLATED_NAME[] tn = names.DangerousGetHandle().ToIEnum<LSA_TRANSLATED_NAME>(sids.Length).ToArray();
|
||||||
var retVal = new SystemAccountInfo[sids.Length];
|
var retVal = new SystemAccountInfo[sids.Length];
|
||||||
for (var i = 0; i < sids.Length; i++)
|
for (var i = 0; i < sids.Length; i++)
|
||||||
retVal[i] = new SystemAccountInfo(tn[i].Name.ToString(), tn[i].Use, sids[i], tn[i].DomainIndex, d);
|
retVal[i] = new SystemAccountInfo(tn[i].Name.ToString(), tn[i].Use, sids[i], tn[i].DomainIndex, d);
|
||||||
|
@ -224,7 +224,7 @@ namespace Vanara.Security.AccessControl
|
||||||
/// <returns>An enumeration of CAPIDs.</returns>
|
/// <returns>An enumeration of CAPIDs.</returns>
|
||||||
public IEnumerable<SecurityIdentifier> GetAvailableCAPIDs()
|
public IEnumerable<SecurityIdentifier> GetAvailableCAPIDs()
|
||||||
{
|
{
|
||||||
ThrowIfLsaError(LsaGetAppliedCAPIDs(svr, out var capIdArray, out var capCount));
|
ThrowIfLsaError(LsaGetAppliedCAPIDs(svr, out SafeLsaMemoryHandle capIdArray, out var capCount));
|
||||||
return capCount == 0 || capIdArray.IsInvalid ? new SecurityIdentifier[0] : capIdArray.DangerousGetHandle().ToIEnum<IntPtr>((int)capCount).Select(p => new SecurityIdentifier(p));
|
return capCount == 0 || capIdArray.IsInvalid ? new SecurityIdentifier[0] : capIdArray.DangerousGetHandle().ToIEnum<IntPtr>((int)capCount).Select(p => new SecurityIdentifier(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,7 +250,7 @@ namespace Vanara.Security.AccessControl
|
||||||
|
|
||||||
private static void SetSystemAccess(SafeLSA_HANDLE hAcct, AccountLogonRights rights)
|
private static void SetSystemAccess(SafeLSA_HANDLE hAcct, AccountLogonRights rights)
|
||||||
{
|
{
|
||||||
var cur = GetSystemAccess(hAcct);
|
AccountLogonRights cur = GetSystemAccess(hAcct);
|
||||||
ThrowIfLsaError(LsaSetSystemAccessAccount(hAcct, (int)(cur | rights)));
|
ThrowIfLsaError(LsaSetSystemAccessAccount(hAcct, (int)(cur | rights)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,8 +260,8 @@ namespace Vanara.Security.AccessControl
|
||||||
|
|
||||||
private SafeLSA_HANDLE GetAccount(string accountName, LsaAccountAccessMask mask = LsaAccountAccessMask.ACCOUNT_VIEW)
|
private SafeLSA_HANDLE GetAccount(string accountName, LsaAccountAccessMask mask = LsaAccountAccessMask.ACCOUNT_VIEW)
|
||||||
{
|
{
|
||||||
var sid = GetSid(accountName);
|
PSID sid = GetSid(accountName);
|
||||||
var res = LsaNtStatusToWinError(LsaOpenAccount(Handle, sid, mask, out var hAcct));
|
Win32Error res = LsaNtStatusToWinError(LsaOpenAccount(Handle, sid, mask, out SafeLSA_HANDLE hAcct));
|
||||||
if (res == Win32Error.ERROR_FILE_NOT_FOUND)
|
if (res == Win32Error.ERROR_FILE_NOT_FOUND)
|
||||||
ThrowIfLsaError(LsaCreateAccount(Handle, sid, mask, out hAcct));
|
ThrowIfLsaError(LsaCreateAccount(Handle, sid, mask, out hAcct));
|
||||||
else
|
else
|
||||||
|
@ -285,7 +285,7 @@ namespace Vanara.Security.AccessControl
|
||||||
private PSID GetSid(string accountName)
|
private PSID GetSid(string accountName)
|
||||||
{
|
{
|
||||||
int sidSize = 0, nameSize = 0;
|
int sidSize = 0, nameSize = 0;
|
||||||
LookupAccountName(svr, accountName, SafePSID.Null, ref sidSize, null, ref nameSize, out var accountType);
|
LookupAccountName(svr, accountName, SafePSID.Null, ref sidSize, null, ref nameSize, out SID_NAME_USE accountType);
|
||||||
var domainName = new System.Text.StringBuilder(nameSize);
|
var domainName = new System.Text.StringBuilder(nameSize);
|
||||||
var sid = new SafePSID(sidSize);
|
var sid = new SafePSID(sidSize);
|
||||||
if (!LookupAccountName(string.Empty, accountName, sid, ref sidSize, domainName, ref nameSize, out accountType))
|
if (!LookupAccountName(string.Empty, accountName, sid, ref sidSize, domainName, ref nameSize, out accountType))
|
||||||
|
@ -311,8 +311,9 @@ namespace Vanara.Security.AccessControl
|
||||||
ctrl = parent;
|
ctrl = parent;
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(userName))
|
if (!string.IsNullOrEmpty(userName))
|
||||||
|
{
|
||||||
user = userName;
|
user = userName;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
using var identity = WindowsIdentity.GetCurrent();
|
using var identity = WindowsIdentity.GetCurrent();
|
||||||
|
@ -369,8 +370,9 @@ namespace Vanara.Security.AccessControl
|
||||||
ctrl = parent;
|
ctrl = parent;
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(userName))
|
if (!string.IsNullOrEmpty(userName))
|
||||||
|
{
|
||||||
user = userName;
|
user = userName;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
using var identity = WindowsIdentity.GetCurrent();
|
using var identity = WindowsIdentity.GetCurrent();
|
||||||
|
@ -393,7 +395,7 @@ namespace Vanara.Security.AccessControl
|
||||||
get => (Rights & right) == right;
|
get => (Rights & right) == right;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
var hAcct = ctrl.GetAccount(user, LsaAccountAccessMask.ACCOUNT_VIEW | LsaAccountAccessMask.ACCOUNT_ADJUST_SYSTEM_ACCESS);
|
SafeLSA_HANDLE hAcct = ctrl.GetAccount(user, LsaAccountAccessMask.ACCOUNT_VIEW | LsaAccountAccessMask.ACCOUNT_ADJUST_SYSTEM_ACCESS);
|
||||||
EnumFlagIndexer<AccountLogonRights> cur = GetSystemAccess(hAcct);
|
EnumFlagIndexer<AccountLogonRights> cur = GetSystemAccess(hAcct);
|
||||||
if (cur[right] == value) return;
|
if (cur[right] == value) return;
|
||||||
cur[right] = value;
|
cur[right] = value;
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
|
using static Vanara.PInvoke.AdvApi32;
|
||||||
|
|
||||||
namespace Vanara.Security
|
namespace Vanara.Security
|
||||||
{
|
{
|
||||||
|
@ -20,7 +24,7 @@ namespace Vanara.Security
|
||||||
{
|
{
|
||||||
var acct = new NTAccount(id.Name);
|
var acct = new NTAccount(id.Name);
|
||||||
|
|
||||||
var si = (SecurityIdentifier) acct.Translate(typeof(SecurityIdentifier));
|
var si = (SecurityIdentifier)acct.Translate(typeof(SecurityIdentifier));
|
||||||
|
|
||||||
return si.IsWellKnown(WellKnownSidType.LocalSystemSid) || si.IsWellKnown(WellKnownSidType.NetworkServiceSid) || si.IsWellKnown(WellKnownSidType.LocalServiceSid) || si.IsWellKnown(WellKnownSidType.ServiceSid);
|
return si.IsWellKnown(WellKnownSidType.LocalSystemSid) || si.IsWellKnown(WellKnownSidType.NetworkServiceSid) || si.IsWellKnown(WellKnownSidType.LocalServiceSid) || si.IsWellKnown(WellKnownSidType.ServiceSid);
|
||||||
}
|
}
|
||||||
|
@ -28,14 +32,15 @@ namespace Vanara.Security
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Runs the specified function as the impersonated Windows identity.</summary>
|
/// <summary>Runs the specified function as the impersonated Windows identity.</summary>
|
||||||
/// <param name="identity">The impersonated identity under which to run the function.</param>
|
/// <param name="identity">The impersonated identity under which to run the function.</param>
|
||||||
/// <param name="func">The System.Func to run.</param>
|
/// <param name="func">The System.Func to run.</param>
|
||||||
public static void Run(this WindowsIdentity identity, Action func)
|
public static void Run(this WindowsIdentity identity, Action func)
|
||||||
{
|
{
|
||||||
if (identity is null)
|
if (identity is null)
|
||||||
|
{
|
||||||
func();
|
func();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#if NETFRAMEWORK
|
#if NETFRAMEWORK
|
||||||
|
@ -91,75 +96,5 @@ namespace Vanara.Security
|
||||||
catch { }
|
catch { }
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*private static bool LookupAccountSid(string computerName, IntPtr sid, out string accountName, out string domainName, out SID_NAME_USE use)
|
|
||||||
{
|
|
||||||
int anLen = 0x100;
|
|
||||||
int dnLen = 0x100;
|
|
||||||
StringBuilder acctName = new StringBuilder(anLen);
|
|
||||||
StringBuilder domName = new StringBuilder(dnLen);
|
|
||||||
if (LookupAccountSid(computerName, sid, acctName, ref anLen, domName, ref dnLen, out use))
|
|
||||||
{
|
|
||||||
accountName = acctName.ToString().TrimEnd('$');
|
|
||||||
domainName = domName.ToString();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
accountName = domainName = null;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool FindUserFromSid(IntPtr incomingSid, string computerName, ref string userName)
|
|
||||||
{
|
|
||||||
SID_NAME_USE use;
|
|
||||||
string acctName, domainName;
|
|
||||||
if (!LookupAccountSid(computerName, incomingSid, out acctName, out domainName, out use))
|
|
||||||
throw new Win32Exception();
|
|
||||||
bool flag = use == SID_NAME_USE.SidTypeUser;
|
|
||||||
if (userName == null)
|
|
||||||
return flag;
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(domainName))
|
|
||||||
domainName = computerName;
|
|
||||||
userName = string.Format("{0}\\{1}", domainName, acctName);
|
|
||||||
return flag;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string FormattedUserNameFromSid(IntPtr incomingSid, string computerName)
|
|
||||||
{
|
|
||||||
string userName = string.Empty;
|
|
||||||
FindUserFromSid(incomingSid, computerName, ref userName);
|
|
||||||
if (!string.IsNullOrEmpty(userName))
|
|
||||||
{
|
|
||||||
SecurityIdentifier identifier = new SecurityIdentifier(incomingSid);
|
|
||||||
string[] strArray = userName.Split(new char[] { '\\' });
|
|
||||||
if (strArray.Length != 2)
|
|
||||||
{
|
|
||||||
return userName;
|
|
||||||
}
|
|
||||||
string str2 = strArray[1];
|
|
||||||
if ((identifier.IsWellKnown(WellKnownSidType.NetworkServiceSid) || identifier.IsWellKnown(WellKnownSidType.AnonymousSid)) || ((identifier.IsWellKnown(WellKnownSidType.LocalSystemSid) || identifier.IsWellKnown(WellKnownSidType.LocalServiceSid)) || identifier.IsWellKnown(WellKnownSidType.LocalSid)))
|
|
||||||
{
|
|
||||||
return str2;
|
|
||||||
}
|
|
||||||
if (string.Compare(strArray[0], computerName, StringComparison.CurrentCultureIgnoreCase) == 0)
|
|
||||||
{
|
|
||||||
userName = str2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return userName;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string FormattedUserNameFromStringSid(string incomingSid, string computerName)
|
|
||||||
{
|
|
||||||
string str = string.Empty;
|
|
||||||
IntPtr zero = IntPtr.Zero;
|
|
||||||
if (!ConvertStringSidToSid(incomingSid, ref zero))
|
|
||||||
{
|
|
||||||
throw new Win32Exception();
|
|
||||||
}
|
|
||||||
str = FormattedUserNameFromSid(zero, computerName);
|
|
||||||
Marshal.FreeHGlobal(zero);
|
|
||||||
return str;
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,4 @@
|
||||||
#if (NET20 || NET35 || NET40 || NET45)
|
using System;
|
||||||
using System;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.DirectoryServices.ActiveDirectory;
|
using System.DirectoryServices.ActiveDirectory;
|
||||||
using Vanara.Extensions.Reflection;
|
using Vanara.Extensions.Reflection;
|
||||||
|
@ -45,5 +44,4 @@ namespace Vanara.Extensions
|
||||||
return new SafeDsHandle(hDc);
|
return new SafeDsHandle(hDc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
|
@ -17,9 +17,18 @@ AccountLogonRights, DesiredAccess, SystemPrivilege
|
||||||
|
|
||||||
</PackageReleaseNotes>
|
</PackageReleaseNotes>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup Condition=" $(TargetFramework.StartsWith('net2')) Or $(TargetFramework.StartsWith('net3')) Or $(TargetFramework.StartsWith('net4')) ">
|
<Choose>
|
||||||
<Reference Include="System.DirectoryServices" />
|
<When Condition=" $(TargetFramework.StartsWith('net2')) Or $(TargetFramework.StartsWith('net3')) Or $(TargetFramework.StartsWith('net4')) ">
|
||||||
</ItemGroup>
|
<ItemGroup>
|
||||||
|
<Reference Include="System.DirectoryServices" />
|
||||||
|
</ItemGroup>
|
||||||
|
</When>
|
||||||
|
<Otherwise>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="System.DirectoryServices" Version="5.0.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Otherwise>
|
||||||
|
</Choose>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Core\Vanara.Core.csproj" />
|
<ProjectReference Include="..\Core\Vanara.Core.csproj" />
|
||||||
<ProjectReference Include="..\PInvoke\NTDSApi\Vanara.PInvoke.NTDSApi.csproj" />
|
<ProjectReference Include="..\PInvoke\NTDSApi\Vanara.PInvoke.NTDSApi.csproj" />
|
||||||
|
|
Loading…
Reference in New Issue