NetValidatePasswordPolicy (advapi32)
Last changed: -167.220.26.214

.
Summary
TODO - a short description

C# Signature:

[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);

VB Signature:

Declare Function NetValidatePasswordPolicy Lib "Netapi32.dll" (TODO) As TODO

User-Defined Types:

[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
}

Alternative Managed API:

Do you know one? Please contribute it!

Notes:

WE NEED SOME HELP WITH THIS ONE. SHOULD HAVE BEEN IN THE "NETAPI32" category.

Tips & Tricks:

Please add some!

Sample Code:

[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);
        }
     }
}

Documentation