diff --git a/src/PasswordFilter/PasswordFilter.rc b/src/PasswordFilter/PasswordFilter.rc index 5bfd174..89eb996 100644 Binary files a/src/PasswordFilter/PasswordFilter.rc and b/src/PasswordFilter/PasswordFilter.rc differ diff --git a/src/PasswordProtection/Interop/NativeMethods.cs b/src/PasswordProtection/Interop/NativeMethods.cs new file mode 100644 index 0000000..9c7699a --- /dev/null +++ b/src/PasswordProtection/Interop/NativeMethods.cs @@ -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(pServerInfo); + + return info; + } + finally + { + if (pServerInfo != IntPtr.Zero) + { + NetApiBufferFree(pServerInfo); + } + } + } + + } +} diff --git a/src/PasswordProtection/Interop/ServerInfo101.cs b/src/PasswordProtection/Interop/ServerInfo101.cs new file mode 100644 index 0000000..9458ed4 --- /dev/null +++ b/src/PasswordProtection/Interop/ServerInfo101.cs @@ -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; + } +} diff --git a/src/PasswordProtection/Interop/ServerPlatform.cs b/src/PasswordProtection/Interop/ServerPlatform.cs new file mode 100644 index 0000000..144f78f --- /dev/null +++ b/src/PasswordProtection/Interop/ServerPlatform.cs @@ -0,0 +1,11 @@ +namespace Lithnet.ActiveDirectory.PasswordProtection +{ + public enum ServerPlatform + { + Dos = 300, + Os2 = 400, + Nt = 500, + Osf = 600, + Vms = 700 + } +} diff --git a/src/PasswordProtection/Interop/ServerTypes.cs b/src/PasswordProtection/Interop/ServerTypes.cs new file mode 100644 index 0000000..7382471 --- /dev/null +++ b/src/PasswordProtection/Interop/ServerTypes.cs @@ -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 + } +} diff --git a/src/PasswordProtection/Lithnet.ActiveDirectory.PasswordProtection.csproj b/src/PasswordProtection/Lithnet.ActiveDirectory.PasswordProtection.csproj index 2d42dd3..dbfe354 100644 --- a/src/PasswordProtection/Lithnet.ActiveDirectory.PasswordProtection.csproj +++ b/src/PasswordProtection/Lithnet.ActiveDirectory.PasswordProtection.csproj @@ -69,9 +69,13 @@ + + + + diff --git a/src/PasswordProtection/Properties/AssemblyInfo.cs b/src/PasswordProtection/Properties/AssemblyInfo.cs index 6868ec2..77ec4d1 100644 --- a/src/PasswordProtection/Properties/AssemblyInfo.cs +++ b/src/PasswordProtection/Properties/AssemblyInfo.cs @@ -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")] diff --git a/src/PasswordProtectionPS/Properties/AssemblyInfo.cs b/src/PasswordProtectionPS/Properties/AssemblyInfo.cs index 2594cc2..24d5c44 100644 --- a/src/PasswordProtectionPS/Properties/AssemblyInfo.cs +++ b/src/PasswordProtectionPS/Properties/AssemblyInfo.cs @@ -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")] diff --git a/src/PasswordProtectionPS/TestIsADUserPasswordCompromised.cs b/src/PasswordProtectionPS/TestIsADUserPasswordCompromised.cs index dff9622..e687653 100644 --- a/src/PasswordProtectionPS/TestIsADUserPasswordCompromised.cs +++ b/src/PasswordProtectionPS/TestIsADUserPasswordCompromised.cs @@ -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 { @@ -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()