.NET Forum / .NET Framework / Interop / September 2006
NetValidatePasswordPolicy - Validating a password against the pass
|
|
Thread rating:  |
Daniel Brown - 17 Sep 2006 04:55 GMT Hello everyone,
I’ve been trying for 2 days now to find any example or using NetValidatePasswordPolicy and actually making it work.
However, I’ll explain my situation first, in case someone can think of another means.
I wish to extend the C#/.NET2.0 Logon Control to validate passwords, which using active directory against the password policy.
I have tried this for many hours different ways which I can think of, Some with success, some with not. In any case, these are only partial solutions and not the full solution.
My Solution (Source code in C# is as followed)
namespace Policy { class Class2 {
public void Solution1() { // Input NET_VALIDATE_PASSWORD_CHANGE_INPUT_ARG Input = new NET_VALIDATE_PASSWORD_CHANGE_INPUT_ARG(); Input.UserAccountName = @"domain\user"; Input.ClearPassword = "password";
// Create a IntPtr IntPtr InputIntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(Input)); // Copy the struct to a IntPtr Marshal.StructureToPtr(Input, InputIntPtr, true);
NET_VALIDATE_OUTPUT_ARG Output = new NET_VALIDATE_OUTPUT_ARG(); // Create a IntPtr for the Output structure IntPtr OutputIntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(Output)); // Copy the Structure to the IntPtr Marshal.StructureToPtr(Output, OutputIntPtr, true);
// Call NetValidatePasswordPolicy NetValidatePasswordPolicy("LDAP://SERVER", System.IntPtr.Zero, NET_VALIDATE_PASSWORD_TYPE.NetValidateAuthentication, InputIntPtr, out OutputIntPtr);
// Copy the OutputPtr into a new structure of OutputNew (NET_VALIDATE_OUTPUT_ARG) NET_VALIDATE_OUTPUT_ARG OutputNew = (NET_VALIDATE_OUTPUT_ARG)Marshal.PtrToStructure(OutputIntPtr, typeof(NET_VALIDATE_OUTPUT_ARG));
}
#region NetValidatePasswordPolicy Enums and Struct's
private enum NET_VALIDATE_PASSWORD_TYPE { NetValidateAuthentication = 1, NetValidatePasswordChange, NetValidatePasswordReset, };
private enum NET_API_STATUS : uint { NERR_Success = 0, NERR_InvalidComputer = 2351, NERR_NotPrimary = 2226, NERR_SpeGroupOp = 2234, NERR_LastAdmin = 2452, NERR_BadPassword = 2203, NERR_PasswordTooShort = 2245, NERR_UserNotFound = 2221, 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 }
[StructLayout(LayoutKind.Sequential)] private struct NET_VALIDATE_PERSISTED_FIELDS { public uint PresentFields; public ulong PasswordLastSet; public ulong BadPasswordTime; public ulong LockoutTime; public uint BadPasswordCount; public uint PasswordHistoryLength; public IntPtr PNET_VALIDATE_PASSWORD_HASH; }
[StructLayout(LayoutKind.Sequential)] private struct NET_VALIDATE_PASSWORD_CHANGE_INPUT_ARG { public NET_VALIDATE_PERSISTED_FIELDS fields; public string ClearPassword; public string UserAccountName; public NET_VALIDATE_PASSWORD_HASH PasswordHash; [MarshalAs(UnmanagedType.I1)] public bool PasswordMatched; }
[StructLayout(LayoutKind.Sequential)] private struct NET_VALIDATE_PASSWORD_HASH { public uint Length; public IntPtr Hash; // How do I populate this? Is IntPtr right? }
[StructLayout(LayoutKind.Sequential)] private struct NET_VALIDATE_PASSWORD_RESET_INPUT_ARG { public NET_VALIDATE_PERSISTED_FIELDS fields; public string ClearPassword; public string UserAccountName; public NET_VALIDATE_PASSWORD_HASH PasswordHash; [MarshalAs(UnmanagedType.I1)] public bool PasswordMustChangeAtNextLogon; [MarshalAs(UnmanagedType.I1)] public bool ClearLockout; }
[StructLayout(LayoutKind.Sequential)] private struct NET_VALIDATE_AUTHENTICATION_INPUT_ARG { public NET_VALIDATE_PERSISTED_FIELDS fields; [MarshalAs(UnmanagedType.I1)] public bool PasswordMatched; }
[StructLayout(LayoutKind.Sequential)] private struct NET_VALIDATE_OUTPUT_ARG { public NET_VALIDATE_PERSISTED_FIELDS fields; public NET_API_STATUS ValidationStatus; }
#endregion
#region DLLImport of NetValidatePasswordPolicy [DllImport("netapi32.dll", SetLastError = true)] private static extern uint NetValidatePasswordPolicy(string lpcwstrServerName, IntPtr Qualifier, NET_VALIDATE_PASSWORD_TYPE TypeOfPassword, IntPtr InputArg, out IntPtr OutputArg); #endregion } }
<---------- END SOURCE CODE -------------------->
Also keep in note, this source code does contain bits and pieces I found during the course of my investigation.
When this code executes, I get the following exception:
System.NullReferenceException: Object reference not set to an instance of an object.
The line which causes the error is:
NET_VALIDATE_OUTPUT_ARG OutputNew = (NET_VALIDATE_OUTPUT_ARG)Marshal.PtrToStructure(OutputIntPtr, typeof(NET_VALIDATE_OUTPUT_ARG));
Why? Well I *THINK* it has something to do with the OutputIntPtr being set to 0 when i do:
// Create a IntPtr for the Output structure IntPtr OutputIntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(Output));
However, I’m unsure of how to do this correctly or even to get the size of a pre-populated struct.
Any insite would be greatly helpful!
Thanks
Daniel
Daniel Brown - 17 Sep 2006 05:07 GMT Iv updated my code a little.
Instead of using :
NET_VALIDATE_PASSWORD_CHANGE_INPUT_ARG Input = new NET_VALIDATE_PASSWORD_CHANGE_INPUT_ARG(); Input.UserAccountName = @"domain\user"; Input.ClearPassword = "password";
Iv changed it to:
NET_VALIDATE_AUTHENTICATION_INPUT_ARG Input = new NET_VALIDATE_AUTHENTICATION_INPUT_ARG(); Input.PasswordMatched = true;
But still no luck, I amstill getting the NullReferance Exception
> Hello everyone, > [quoted text clipped - 179 lines] > > Daniel Daniel Brown - 17 Sep 2006 07:26 GMT After more trial and error, I have finally got it to return NERR_Success.... no matter what complixity req it doesnt match. I cannot get it to fail.
The Source Code :
class Class2 { private IntPtr MarshalToPointer(object data) { IntPtr buf = Marshal.AllocHGlobal(Marshal.SizeOf(data)); Marshal.StructureToPtr(data,buf, false); return buf; }
private object MarshalToStruct(IntPtr buf, Type t) { return Marshal.PtrToStructure(buf, t); } public void Solution1() { try { // Input NET_VALIDATE_AUTHENTICATION_INPUT_ARG Input = new NET_VALIDATE_AUTHENTICATION_INPUT_ARG(); Input.PasswordMatched = false;
//NET_VALIDATE_PASSWORD_CHANGE_INPUT_ARG Input = new NET_VALIDATE_PASSWORD_CHANGE_INPUT_ARG(); //Input.UserAccountName = @"VEXTHAL\Daniel"; //Input.ClearPassword = "drvt783c6";
IntPtr InputIntPtr = MarshalToPointer(Input);
// Create a IntPtr //IntPtr InputIntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(Input));
// Copy the struct to a IntPtr Marshal.StructureToPtr(Input, InputIntPtr, true);
NET_VALIDATE_OUTPUT_ARG Output = new NET_VALIDATE_OUTPUT_ARG();
// Create a IntPtr for the Output structure IntPtr OutputIntPtr = Marshal.AllocHGlobal(1024); // Copy the Structure to the IntPtr Marshal.StructureToPtr(Output, OutputIntPtr, true);
IntPtr lpstruct = MarshalToPointer(Output); //…and then the pointer to the pointer: IntPtr lppstruct = MarshalToPointer(lpstruct);
// Call NetValidatePasswordPolicy NET_API_STATUS rval = NetValidatePasswordPolicy(null, System.IntPtr.Zero, NET_VALIDATE_PASSWORD_TYPE.NetValidateAuthentication, InputIntPtr, out lppstruct);
Console.WriteLine(rval.ToString());
// Copy the OutputPtr into a new structure of OutputNew (NET_VALIDATE_OUTPUT_ARG) NET_VALIDATE_OUTPUT_ARG OutputNew = (NET_VALIDATE_OUTPUT_ARG )MarshalToStruct(OutputIntPtr, typeof(NET_VALIDATE_OUTPUT_ARG));
Console.Write(OutputNew.ValidationStatus.ToString());
} catch (Exception ex) { Console.Write(ex.ToString()); } finally { }
}
#region NetValidatePasswordPolicy Enums and Struct's
private enum NET_VALIDATE_PASSWORD_TYPE { NetValidateAuthentication = 1, NetValidatePasswordChange, NetValidatePasswordReset, };
private enum NET_API_STATUS : uint { NERR_Success = 0, NERR_InvalidComputer = 2351, NERR_NotPrimary = 2226, NERR_SpeGroupOp = 2234, NERR_LastAdmin = 2452, NERR_BadPassword = 2203, NERR_PasswordTooShort = 2245, NERR_UserNotFound = 2221, 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 }
[StructLayout(LayoutKind.Sequential)] private struct NET_VALIDATE_PERSISTED_FIELDS { public uint PresentFields; public ulong PasswordLastSet; public ulong BadPasswordTime; public ulong LockoutTime; public uint BadPasswordCount; public uint PasswordHistoryLength; public IntPtr PNET_VALIDATE_PASSWORD_HASH; }
[StructLayout(LayoutKind.Sequential)] private struct NET_VALIDATE_PASSWORD_CHANGE_INPUT_ARG { public NET_VALIDATE_PERSISTED_FIELDS fields; public string ClearPassword; public string UserAccountName; public NET_VALIDATE_PASSWORD_HASH PasswordHash; [MarshalAs(UnmanagedType.I1)] public bool PasswordMatched; }
[StructLayout(LayoutKind.Sequential)] private struct NET_VALIDATE_PASSWORD_HASH { public uint Length; public IntPtr Hash; // How do I populate this? Is IntPtr right? }
[StructLayout(LayoutKind.Sequential)] private struct NET_VALIDATE_PASSWORD_RESET_INPUT_ARG { public NET_VALIDATE_PERSISTED_FIELDS fields; public string ClearPassword; public string UserAccountName; public NET_VALIDATE_PASSWORD_HASH PasswordHash; [MarshalAs(UnmanagedType.I1)] public bool PasswordMustChangeAtNextLogon; [MarshalAs(UnmanagedType.I1)] public bool ClearLockout; }
[StructLayout(LayoutKind.Sequential)] private struct NET_VALIDATE_AUTHENTICATION_INPUT_ARG { public NET_VALIDATE_PERSISTED_FIELDS fields; [MarshalAs(UnmanagedType.I1)] public bool PasswordMatched; }
[StructLayout(LayoutKind.Sequential)] private struct NET_VALIDATE_OUTPUT_ARG { public NET_VALIDATE_PERSISTED_FIELDS fields; public NET_API_STATUS ValidationStatus; }
#endregion
#region DLLImport of NetValidatePasswordPolicy [DllImport("netapi32.dll", SetLastError = true)] private static extern NET_API_STATUS NetValidatePasswordPolicy(string lpcwstrServerName, IntPtr Qualifier, NET_VALIDATE_PASSWORD_TYPE TypeOfPassword, IntPtr InputArg, out IntPtr OutputArg); #endregion }
=== END SOURCE ===
> Iv updated my code a little. > [quoted text clipped - 196 lines] > > > > Daniel
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|