RE: Validating an NT password

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance

From: Peter Huang (v-phuang_at_online.microsoft.com)
Date: 04/28/04


Date: Wed, 28 Apr 2004 03:18:27 GMT

Hi Charles,

It seems that there is a server error about my last post, here I repost the
code as below.

Also thank for Hayato sharing the knowledge in the newsgroup with us. The
trick to use the netuserchangepassword to change the password the same with
before one will do the job. But sometimes the domain policy will limit the
user to change password which can not be same with the latest severals.
e.g. If the old password is A, then for security concern the domain policy
will request that the password the user wants to change must be different
from A. So in this way, sometimes the authentication will fail because the
domain policy.

LogonUser do have some limitation with windows 2000/NT.
>From the KB article below.

HOWTO: Validate User Credentials on Microsoft Operating Systems
http://support.microsoft.com/?id=180548

Note LogonUser Win32 API does not require TCB privilege in Microsoft
Windows Server 2003, however, for downlevel compatibility, this is still
the best approach.

On Windows XP, it is no longer required that a process have the SE_TCB_NAME
privilege in order to call LogonUser. Therefore, the simplest method to
validate a user's credentials on Windows XP, is to call the LogonUser API.

So I think we can use the LogonUser with windows XP and windows 2003.

Or

We can use the SSPI
HOWTO: Validate User Credentials from Visual Basic by Using SSPI
http://support.microsoft.com/default.aspx?scid=kb;EN-US;279815

I think we'd better try to use the LogonUser API. Here is the C# code.
const long LOGON32_LOGON_INTERACTIVE = 2;
const long LOGON32_LOGON_NETWORK = 3;

// Declare the logon providers as constants
const long LOGON32_PROVIDER_DEFAULT = 0;
const long LOGON32_PROVIDER_WINNT50 = 3;
const long LOGON32_PROVIDER_WINNT40 = 2;
const long LOGON32_PROVIDER_WINNT35 = 1;

[DllImport("advapi32.dll",EntryPoint = "LogonUser")]
private static extern bool LogonUser(
string lpszUsername,
string lpszDomain,
string lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);

/// <summary>
/// Validates the user based on the supplied credentials
/// </summary>
/// <param name="Username">The username to use when valdiating the
user</param>
/// <param name="Password">The password to use when validating the
user</param>
/// <param name="Domain">The account domain or machine name to use when
validating the user</param>
/// <returns>Returns true if the credentials are valid, and false
otherwise</returns>
private bool ValidateLogin(
string Username,
string Password,
string Domain)
{
// This is the token returned by the API call
// Look forward to a future article covering
// the uses of it
IntPtr token = new IntPtr(0);
token = IntPtr.Zero;

// Call the API
if (LogonUser(
Username,
Domain,
Password,
(int)LOGON32_LOGON_NETWORK,
(int)LOGON32_PROVIDER_DEFAULT,
ref token))
{
//' Since the API returned TRUE, return TRUE to the caller
return true;
}
else
{
//' Bad credentials, return FALSE
return false;
}
}
private void button1_Click(object sender, System.EventArgs e)
{
if(ValidateLogin("username","password","domain"))
MessageBox.Show("Ok");
else
MessageBox.Show("Failed");
}

Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.



Relevant Pages

  • Why is Marshal::StringToHGlobalAnsi argument not const?
    ... I try to be const correct everywhere and found that I can't pass a const ... String to this API. ... const char* chars = ...
    (microsoft.public.dotnet.languages.vc)
  • Using the LogonUser API
    ... I am attempting to impersonate a user using the LogonUser and related APIs. ... ByVal lpszDomain As String, ByVal lpszPassword As String, _ ... Private Declare Function ImpersonateLoggedOnUser Lib "advapi32" (_ ... Dim ProfileHandle As Long ...
    (microsoft.public.vb.general.discussion)
  • Using the LogonUser API
    ... I am attempting to impersonate a user using the LogonUser and related APIs. ... ByVal lpszDomain As String, ByVal lpszPassword As String, _ ... Private Declare Function ImpersonateLoggedOnUser Lib "advapi32" (_ ... Dim ProfileHandle As Long ...
    (microsoft.public.vb.winapi)
  • how can you impersonate on a remote machine
    ... "The local computer is the computer from which LogonUser was called. ... lpszUsername As [String], ByVal lpszDomain As, ByVal lpszPassword ... Dim dupeTokenHandle As New IntPtr ... ' Free the tokens. ...
    (microsoft.public.dotnet.security)
  • problems in implementing "LogonUser" API with Win2k server
    ... Private Declare Function GetUserName Lib "advapi32.dll" _ ... Private Declare Function LogonUser Lib "advapi32.dll" ... Const LOGON32_LOGON_NETWORK = 3 ... Both are having Windows 2000 ...
    (microsoft.public.win2000.security)