[DllImport("Netapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern NET_API_STATUS NetValidatePasswordPolicy(
[MarshalAs(UnmanagedType.LPWStr)]
string ServerName,
IntPtr Qualifier,
NET_VALIDATE_PASSWORD_TYPE ValidationType,
IntPtr InputArg,
ref IntPtr OutputArg);
Declare Function NetValidatePasswordPolicy Lib "Netapi32.dll" (TODO) As TODO
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct NET_VALIDATE_OUTPUT_ARG
{
public NET_VALIDATE_PERSISTED_FIELDS ChangedPersistedFields;
public NET_API_STATUS ValidationStatus;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct NET_VALIDATE_PASSWORD_HASH
{
public uint Length;
public IntPtr Hash;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct NET_VALIDATE_AUTHENTICATION_INPUT_ARG
{
public NET_VALIDATE_PERSISTED_FIELDS InputPersistedFields;
[MarshalAs(UnmanagedType.I1)]
public bool PasswordMatched;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct NET_VALIDATE_PASSWORD_CHANGE_INPUT_ARG
{
public NET_VALIDATE_PERSISTED_FIELDS InputPersistedFields;
// Don't use a managed string, you can't securely clean that up.
// Use Marshal.SecureStringToBSTR() and Marshal.ZeroFreeBSTR() to get and clean up a native string pointer.
public IntPtr ClearPassword;
[MarshalAs(UnmanagedType.LPWStr)]
public string UserAccountName;
public NET_VALIDATE_PASSWORD_HASH HashedPassword;
[MarshalAs(UnmanagedType.I1)]
public bool PasswordMatched;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct NET_VALIDATE_PASSWORD_RESET_INPUT_ARG
{
public NET_VALIDATE_PERSISTED_FIELDS InputPersistedFields;
[MarshalAs(UnmanagedType.LPWStr)]
public string ClearPassword;
[MarshalAs(UnmanagedType.LPWStr)]
public string UserAccountName;
public NET_VALIDATE_PASSWORD_HASH HashedPassword;
[MarshalAs(UnmanagedType.I1)]
public bool PasswordMustChangeAtNextLogon;
[MarshalAs(UnmanagedType.I1)]
public bool ClearLockout;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct NET_VALIDATE_PERSISTED_FIELDS
{
public uint PresentFields;
public ComTypes.FILETIME PasswordLastSet;
public ComTypes.FILETIME BadPasswordTime;
public ComTypes.FILETIME LockoutTime;
public uint BadPasswordCount;
public uint PasswordHistoryLength;
public IntPtr PasswordHistory;
}
internal enum NET_API_STATUS : uint
{
ERROR_ACCESS_DENIED = 5,
ERROR_NOT_ENOUGH_MEMORY = 8,
ERROR_INVALID_PARAMETER = 87,
ERROR_INVALID_NAME = 123,
ERROR_INVALID_LEVEL = 124,
ERROR_SESSION_CREDENTIAL_CONFLICT = 1219,
NERR_Success = 0,
NERR_InvalidComputer = 2351,
NERR_BadPassword = 2203,
NERR_UserNotFound = 2221,
NERR_AccountLockedOut = 2702,
NERR_PasswordTooRecent = 2246,
NERR_PasswordHistConflict = 2244,
NERR_PasswordTooShort = 2245,
NERR_PasswordTooLong = 2703,
NERR_PasswordNotComplexEnough = 2704,
NERR_PasswordFilterError = 2705,
NERR_PasswordMustChange = 2701,
NERR_PasswordExpired = 2242
}
internal enum NET_VALIDATE_PASSWORD_TYPE
{
NetValidateAuthentication = 1,
NetValidatePasswordChange,
NetValidatePasswordReset
}
Do you know one? Please contribute it!
WE NEED SOME HELP WITH THIS ONE. SHOULD HAVE BEEN IN THE "NETAPI32" category.
Please add some!
[DllImport("Netapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern NET_API_STATUS NetValidatePasswordPolicyFree(ref IntPtr OutputArg);
private void Main()
{
string serverName = @"\\servername";
var inputArgs = new NET_VALIDATE_PASSWORD_CHANGE_INPUT_ARG();
inputArgs.PasswordMatched = true;
inputArgs.UserAccountName = @"accountname";
var outputArgs = new NET_VALIDATE_OUTPUT_ARG();
IntPtr inputPointer = IntPtr.Zero;
IntPtr outputPointer = IntPtr.Zero;
try
{
inputArgs.ClearPassword = Marshal.StringToBSTR(@"password");
// If using a secure string
//inputArgs.ClearPassword = Marshal.SecureStringToBSTR(secureStringPassword);
inputPointer = Marshal.AllocHGlobal(Marshal.SizeOf(inputArgs));
Marshal.StructureToPtr(inputArgs, inputPointer, false);
NET_API_STATUS status = NetValidatePasswordPolicy(serverName, IntPtr.Zero, NET_VALIDATE_PASSWORD_TYPE.NetValidatePasswordChange, inputPointer, ref outputPointer);
if (status == NET_API_STATUS.NERR_Success)
{
outputArgs = (NET_VALIDATE_OUTPUT_ARG)Marshal.PtrToStructure(outputPointer, typeof(NET_VALIDATE_OUTPUT_ARG));
if (outputArgs.ValidationStatus == NET_API_STATUS.NERR_Success)
{
// Ok
}
else
{
Console.WriteLine(outputArgs.ValidationStatus);
}
}
else
{
Console.WriteLine(status);
}
}
finally
{
if (outputPointer != IntPtr.Zero)
{
NetValidatePasswordPolicyFree(ref outputPointer);
}
if (inputArgs.ClearPassword != IntPtr.Zero)
{
Marshal.ZeroFreeBSTR(inputArgs.ClearPassword);
}
if (inputPointer != IntPtr.Zero)
{
Marshal.FreeHGlobal(inputPointer);
}
}
}