Skip to content

Commit

Permalink
Fixes an issue where Test-IsADUserPasswordCompromised cmdlet would fa…
Browse files Browse the repository at this point in the history
…il when a server name was not specified, and NTLM was disabled for the calling user
  • Loading branch information
ryannewington committed Dec 4, 2022
1 parent 9aefb74 commit a5ed018
Show file tree
Hide file tree
Showing 9 changed files with 154 additions and 7 deletions.
Binary file modified src/PasswordFilter/PasswordFilter.rc
Binary file not shown.
53 changes: 53 additions & 0 deletions src/PasswordProtection/Interop/NativeMethods.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;

namespace Lithnet.ActiveDirectory.PasswordProtection
{
public static class NativeMethods
{
[DllImport("Netapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern int NetServerGetInfo(string serverName, int level, out IntPtr pServerInfo);

[DllImport("NetApi32.dll")]
private static extern int NetApiBufferFree(IntPtr buffer);

public static bool IsDc()
{
var info = GetServerInfo();
return info.Type.HasFlag(ServerTypes.DomainCtrl) || info.Type.HasFlag(ServerTypes.BackupDomainCtrl);
}

public static ServerInfo101 GetServerInfo()
{
return GetServerInfo(null);
}

public static ServerInfo101 GetServerInfo(string server)
{
IntPtr pServerInfo = IntPtr.Zero;

try
{
int result = NetServerGetInfo(server, 101, out pServerInfo);

if (result != 0)
{
throw new Win32Exception(result);
}

var info = Marshal.PtrToStructure<ServerInfo101>(pServerInfo);

return info;
}
finally
{
if (pServerInfo != IntPtr.Zero)
{
NetApiBufferFree(pServerInfo);
}
}
}

}
}
22 changes: 22 additions & 0 deletions src/PasswordProtection/Interop/ServerInfo101.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System.Runtime.InteropServices;

namespace Lithnet.ActiveDirectory.PasswordProtection
{
[StructLayout(LayoutKind.Sequential)]
public struct ServerInfo101
{
public ServerPlatform PlatformId;

[MarshalAs(UnmanagedType.LPWStr)]
public string Name;

public int VersionMajor;

public int VersionMinor;

public ServerTypes Type;

[MarshalAs(UnmanagedType.LPWStr)]
public string Comment;
}
}
11 changes: 11 additions & 0 deletions src/PasswordProtection/Interop/ServerPlatform.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Lithnet.ActiveDirectory.PasswordProtection
{
public enum ServerPlatform
{
Dos = 300,
Os2 = 400,
Nt = 500,
Osf = 600,
Vms = 700
}
}
42 changes: 42 additions & 0 deletions src/PasswordProtection/Interop/ServerTypes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System;

namespace Lithnet.ActiveDirectory.PasswordProtection
{
[Flags]
public enum ServerTypes : uint
{
Workstation = 0x00000001,
Server = 0x00000002,
SqlServer = 0x00000004,
DomainCtrl = 0x00000008,
BackupDomainCtrl = 0x00000010,
TimeSource = 0x00000020,
AppleFilingProtocol = 0x00000040,
Novell = 0x00000080,
DomainMember = 0x00000100,
PrintQueueServer = 0x00000200,
DialinServer = 0x00000400,
XenixServer = 0x00000800,
UnixServer = 0x00000800,
NT = 0x00001000,
WindowsForWorkgroups = 0x00002000,
MicrosoftFileAndPrintServer = 0x00004000,
NTServer = 0x00008000,
BrowserService = 0x00010000,
BackupBrowserService = 0x00020000,
MasterBrowserService = 0x00040000,
DomainMaster = 0x00080000,
OSF1Server = 0x00100000,
VMSServer = 0x00200000,
Windows = 0x00400000,
DFS = 0x00800000,
NTCluster = 0x01000000,
TerminalServer = 0x02000000,
VirtualNTCluster = 0x04000000,
DCE = 0x10000000,
AlternateTransport = 0x20000000,
LocalListOnly = 0x40000000,
PrimaryDomain = 0x80000000,
All = 0xFFFFFFFF
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,13 @@
<Compile Include="Extensions.cs" />
<Compile Include="FilterInterface.cs" />
<Compile Include="HashRangeGroup.cs" />
<Compile Include="Interop\ServerInfo101.cs" />
<Compile Include="Interop\ServerPlatform.cs" />
<Compile Include="Interop\ServerTypes.cs" />
<Compile Include="IStore.cs" />
<Compile Include="CryptoLib\MD4.cs" />
<Compile Include="CryptoLib\MD4CryptoServiceProvider.cs" />
<Compile Include="Interop\NativeMethods.cs" />
<Compile Include="OperationProgress.cs" />
<Compile Include="PasswordTestResult.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
Expand Down
4 changes: 2 additions & 2 deletions src/PasswordProtection/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.7239.0")]
[assembly: AssemblyVersion("1.0.7243.0")]
[assembly: AssemblyFileVersion("1.0.7243.0")]
[assembly: AssemblyVersion("1.0.7244.0")]
[assembly: AssemblyFileVersion("1.0.7244.0")]
4 changes: 2 additions & 2 deletions src/PasswordProtectionPS/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.7239.0")]
[assembly: AssemblyVersion("1.0.7243.0")]
[assembly: AssemblyFileVersion("1.0.7243.0")]
[assembly: AssemblyVersion("1.0.7244.0")]
[assembly: AssemblyFileVersion("1.0.7244.0")]
21 changes: 18 additions & 3 deletions src/PasswordProtectionPS/TestIsADUserPasswordCompromised.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
using System;
using System.DirectoryServices.ActiveDirectory;
using System.Management.Automation;
using System.Security.Principal;
using Lithnet.ActiveDirectory.PasswordProtection;
using DSInternals.Replication;
using DSInternals.Common.Data;
using DSInternals.Replication;

namespace Lithnet.ActiveDirectory.PasswordProtection.PowerShell
{
Expand Down Expand Up @@ -37,7 +37,22 @@ protected override void BeginProcessing()
{
Global.OpenExistingDefaultOrThrow();
base.BeginProcessing();
this.client = new DirectoryReplicationClient(this.Server ?? Environment.GetEnvironmentVariable("UserDNSDomain"), RpcProtocol.TCP, this.Credential?.GetNetworkCredential());

string server = this.Server;

if (server == null)
{
if (NativeMethods.IsDc())
{
server = Environment.MachineName;
}
else
{
server = Domain.GetComputerDomain().FindDomainController(LocatorOptions.WriteableRequired).Name;
}
}

this.client = new DirectoryReplicationClient(server, RpcProtocol.TCP, this.Credential?.GetNetworkCredential());
}

protected override void ProcessRecord()
Expand Down

0 comments on commit a5ed018

Please sign in to comment.