1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
| using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
namespace NetValidatePassword
{
/// <summary>
/// Valider un mot de passe sur l'historique des mots de passes d'un usager.
/// </summary>
class NetValidatePassword
{
private static string[] args;
public static void Usage()
{
Console.WriteLine("Usage: {0} Idul password");
}
static NetValidatePassword()
{
args = Environment.GetCommandLineArgs();
}
/// <summary>
/// Point d'entrée principal de l'application.
/// </summary>
[STAThread]
static Int32 Main(string[] args)
{
if (args.Length < 2)
{
Usage();
return 2;
}
// string Message;
string Idul = args[0];
string password = args[1]; // New Password
string domaine = "MON_DOMAINE";
if (Idul.IndexOf("@") > 0)
{
String[] identite = Idul.Split('@');
Idul = identite[0];
domaine = identite[1];
Console.WriteLine("Domaine:"+domaine);
}
NET_VALIDATE_PASSWORD_CHANGE_INPUT_ARG InputChange = new
NET_VALIDATE_PASSWORD_CHANGE_INPUT_ARG();
InputChange.UserAccountName = @"MON_DOMAINE\" + Idul;
InputChange.ClearPassword = password;
InputChange.PasswordMatched = true;
//Créer le hash de password
Byte[] passwordToHash = new UnicodeEncoding().GetBytes(password);
Byte[] hashPassword = ((HashAlgorithm) CryptoConfig.CreateFromName("MD5")).ComputeHash(passwordToHash);
InputChange.PasswordHash.Hash = Marshal.StringToHGlobalAuto(hashPassword.ToString());
InputChange.PasswordHash.Length = (uint) Marshal.SizeOf(InputChange.PasswordHash);
// Préparer le PasswordHistory
NET_VALIDATE_PASSWORD_HASH PasswordHistory = new NET_VALIDATE_PASSWORD_HASH();
PasswordHistory.Hash = Marshal.AllocHGlobal(256);
PasswordHistory.Length = (uint) Marshal.SizeOf(PasswordHistory);
IntPtr IntPtrPasswordHistory = Marshal.AllocHGlobal(Marshal.SizeOf(PasswordHistory));
// Le transférer dans la structure
Marshal.StructureToPtr(PasswordHistory, IntPtrPasswordHistory, true);
InputChange.fields.PNET_VALIDATE_PASSWORD_HASH = IntPtrPasswordHistory;
// Create a IntPtr
IntPtr InputChangeIntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(InputChange));
// Copy the struct to a IntPtr
Marshal.StructureToPtr(InputChange, InputChangeIntPtr, true);
NET_VALIDATE_OUTPUT_ARG Output = new NET_VALIDATE_OUTPUT_ARG();
NET_VALIDATE_PASSWORD_HASH OutPasswordHistory = new NET_VALIDATE_PASSWORD_HASH();
OutPasswordHistory.Hash = Marshal.AllocHGlobal(256);
OutPasswordHistory.Length = (uint) Marshal.SizeOf(OutPasswordHistory);
// Copy the Structure to the IntPtr
Output.fields.PNET_VALIDATE_PASSWORD_HASH = Marshal.AllocHGlobal(Marshal.SizeOf(OutPasswordHistory));
// Create Net_API_Status
NET_API_STATUS net_api_status = new NET_API_STATUS();
Output.ValidationStatus = net_api_status;
// Create a IntPtr for the Output structure
IntPtr OutputIntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(Output));
Marshal.StructureToPtr(Output, OutputIntPtr, true);
Console.WriteLine("Output.fields.PNET_VALIDATE_PASSWORD_HASH: " + Output.fields.PNET_VALIDATE_PASSWORD_HASH.ToString());
try
{
Console.WriteLine(NET_VALIDATE_PASSWORD_TYPE.NetValidatePasswordChange.ToString());
// Call NetValidatePasswordPolicy
NetValidatePasswordPolicy(null, System.IntPtr.Zero, NET_VALIDATE_PASSWORD_TYPE.NetValidatePasswordChange, InputChangeIntPtr, out OutputIntPtr);
Console.WriteLine("ValidationStatus: " + Output.ValidationStatus.ToString());
Console.WriteLine("PasswordHistoryLength: " + Output.fields.PasswordHistoryLength);
Console.WriteLine("PasswordLastSet: " + Output.fields.PasswordLastSet);
}
catch(COMException e)
{
Console.WriteLine("Erreur NullReferenceException: " + e.StackTrace + "\n " + e.Message);
return 9;
}
catch (NullReferenceException e)
{
Console.WriteLine("Erreur NullReferenceException: " + e.StackTrace + "\n " + e.Message);
return 9;
}
catch (Exception e)
{
Console.WriteLine("Erreur NullReferenceException: " + e.StackTrace + "\n " + e.Message);
return 9;
}
catch
{
Console.WriteLine("Erreur");
return 9;
}
// Copy the OutputPtr into a new structure of OutputNew
NET_VALIDATE_OUTPUT_ARG OutputNew = (NET_VALIDATE_OUTPUT_ARG)Marshal.PtrToStructure(OutputIntPtr, typeof(NET_VALIDATE_OUTPUT_ARG));
Console.WriteLine("PasswordLastSet: " + OutputNew.fields.PasswordLastSet.ToString());
Console.WriteLine("ValidationStatus: " + OutputNew.ValidationStatus.ToString());
Console.WriteLine("PasswordHistoryLength: " + OutputNew.fields.PasswordHistoryLength.ToString());
Console.WriteLine("PresentFields: " + OutputNew.fields.PresentFields.ToString());
Marshal.FreeHGlobal(Output.fields.PNET_VALIDATE_PASSWORD_HASH);
Marshal.FreeHGlobal(PasswordHistory.Hash);
Marshal.FreeHGlobal(OutPasswordHistory.Hash);
Marshal.FreeHGlobal(OutputIntPtr);
Marshal.FreeHGlobal(IntPtrPasswordHistory);
Marshal.FreeHGlobal(InputChangeIntPtr);
return 0;
}
#region DLLImport
[DllImport("netapi32.dll", SetLastError = true)]
public static extern uint NetValidatePasswordPolicy(string
lpcwstrServerName, IntPtr Qualifier, NET_VALIDATE_PASSWORD_TYPE
TypeOfPassword, IntPtr InputArg, out IntPtr OutputArg);
[DllImport("ADVAPI32.DLL", SetLastError=true)]
internal static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
int dwLogonType, int dwLogonProvider, out IntPtr phToken);
[DllImport("ADVAPI32.DLL", SetLastError=true)]
internal static extern bool ImpersonateLoggedOnUser(IntPtr phToken);
[DllImport("ADVAPI32.DLL", SetLastError=true)]
internal static extern bool RevertToSelf();
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool CloseHandle(IntPtr handle);
#endregion
#region Définition des types utilisé par NetValidatePasswordPolicy
public enum NET_VALIDATE_PASSWORD_TYPE
{
NetValidateAuthentication = 1,
NetValidatePasswordChange,
NetValidatePasswordReset,
}
[StructLayout(LayoutKind.Sequential)]
public 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)]
public struct NET_VALIDATE_PASSWORD_HASH
{
public uint Length;
public IntPtr Hash; // How do I populate this? Is IntPtr right?
}
[StructLayout(LayoutKind.Sequential)]
public 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;
}
public 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)]
public struct NET_VALIDATE_OUTPUT_ARG
{
public NET_VALIDATE_PERSISTED_FIELDS fields;
public NET_API_STATUS ValidationStatus;
}
#endregion
}
} |