We use Active Directory Application Mode (ADAM) and .NET framework 4.0.
We call PrincipalContext.ValidateCredential with a valid user name (and a non-empty password) but a string.empty password : the method return true.
If we call with an invalid user name it returns False. If we call with a valid user name but a non-null/non-empty password it returns False. If we use a Null password it returns an exception.
According to the documentation, a call to "PrincipalContext.ValidateCredential" can return true with user name AND password set to NULL (http://msdn.microsoft.com/en-us/library/bb154889%28v=vs.100%29.aspx).
It's easy to validate the parameter and prevent a Null password but our security department required a more robust solution : we consider this is a bug. Since it's possible to construct a valid PrincipalContext that show that behavior what I'm looking for is a fix of the API so in all use case, if a user name is provided then the ValidateCredentials call return True only if the password match.
I'll post code sample in few
EDIT : there's code to reproduce. Change the Adam string to match yours.
EDIT : The method return True for a string.empty parameter but the "bad password count" is incremented.
Imports System.DirectoryServices Imports System.Configuration Imports System.Collections.Specialized Imports System.DirectoryServices.AccountManagement Imports System.Text.RegularExpressions Public Class Form1 Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click Dim username As String = TextBox1.Text Dim password As String = TextBox2.Text Dim valid As Boolean Using context As PrincipalContext = New PrincipalContext(ContextType.ApplicationDirectory, _ "tnds30vd.dev02.avdl.com:389", _"CN=Users,OU=Fonc,OU=IECE,DC=dev02,DC=avdl,DC=com", _ ContextOptions.SimpleBind) valid = context.ValidateCredentials(DistinguishedNameFromUsername(username, "CN=Users,OU=Fonc,OU=IECE,DC=dev02,DC=avdl,DC=com"), password, ContextOptions.SimpleBind) End Using If valid Then MsgBox("User valide!") Else MsgBox("User NON valide!", MsgBoxStyle.Critical) End If End Sub ''' <summary> ''' ''' </summary> ''' <param name="searchFilter"></param> ''' <returns></returns> ''' <remarks>Cette fonction a été construite selon la section Special Characters http://msdn.microsoft.com/en-us/library/aa746475.aspx </remarks> Private Shared Function EscapeLdapSearchFilter(searchFilter As String) As String Dim escape As New System.Text.StringBuilder For Each currentChar As Char In searchFilter Select Case currentChar Case "\"c escape.Append("\5c") Case "*"c escape.Append("\2a") Case "("c escape.Append("\28") Case ")"c escape.Append("\29") Case Nothing escape.Append("\00") Case "/"c escape.Append("\2f") Case Else escape.Append(currentChar) End Select Next Return escape.ToString() End Function Private Shared Function EscapeDN(ByVal name As String) As String Dim escape As New System.Text.StringBuilder If name.Length > 0 AndAlso (name.Substring(0, 1) = " " OrElse name.Substring(0, 1) = "#") Then escape.Append("\") ' Add the leading backslash if needed End If For Each currentChar As Char In name Select Case currentChar Case "'"c escape.Append("\27") Case "&"c escape.Append("\26") Case "|"c escape.Append("\7c") Case "!"c escape.Append("\21") Case "\"c escape.Append("\5c") Case ","c escape.Append("\2c") Case "+"c escape.Append("\2b") Case """"c escape.Append("\22") Case "<"c escape.Append("\3c") Case ">"c escape.Append("\3e") Case ";"c escape.Append("\3b") Case Microsoft.VisualBasic.Chr(10) escape.Append("\0a") Case Microsoft.VisualBasic.Chr(13) escape.Append("\0d") Case "="c escape.Append("\3d") Case "/"c escape.Append("\2f") Case Else escape.Append(currentChar) End Select Next If name.Length > 1 AndAlso (name.Substring(name.Length - 1) = " ") Then escape.Insert(escape.Length - 1, "\") ' Add the trailing backslash if needed End If Return escape.ToString End Function Private Shared Function DistinguishedNameFromUsername(username As String, container As String) As String Return String.Format("CN={0},{1}", EscapeDN(username), container) End Function End Class