"fomalhaut" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Hi All,
>
> I'm builing an application that requires domain admin access to run,
> and I'm trying to allow for the application to be run as a normal user
> and allow the user to provide it with a username/password that has the
> access.
>
> I have a method that will check if the username/password is correct,
> however, it will only authenticate the user running the program...
>
> Here's the method:
>
> public static bool validatePassword(string adUserName, string
> adPassword)
> {
> DirectoryEntry de = new DirectoryEntry(null, "WDE" +
> "\\" + adUserName, adPassword);
> try
> {
> object o = de.NativeObject;
> DirectorySearcher ds = new DirectorySearcher(de);
> ds.Filter = "samaccountname=" + adUserName;
> ds.PropertiesToLoad.Add("cn");
> SearchResult sr = ds.FindOne();
> if (sr == null) throw new Exception();
> return true;
> }
> catch
> {
> return false;
> }
> }
>
> If I check the username/password of the person that is running the
> application, it works fine. If I provide any other username/password,
> it fails in the "object o = de.NativeObject;".
>
> Any ideas as to why it's happening?
>
> Cheers,
> Nathan Manzi
>
start by a change of your catch clause into:
catch(System.Runtime.InteropServices.COMException ex)
{
Console.WriteLine(ex);
return false;
}
and it will tell you why, however, there are other things wrong with your code.
This aside, you should not use this to authenticate a windows user, AD is not an
authentication service.
Use Win32 "LogonUser" or better use the SSPI in V2 of the framework . Following is a
complete sample that illustrates you how to authenticate windows users , both local and
domain users, using the WindowsIdentity and the NegotiateStream class in V2 .
using System;
using System.Net;
using System.Net.Sockets;
using System.Net.Security;
using System.Security.Principal;
class Program
{
static void Main(string[] args)
{
// pass account name, password and domain name as arguments. For local accounts,
pass the machine name as domain name.
WindowsIdentity id = SSPIHelper.LogonUser("uuuuuu", "pppppp", "ddddd");
if(id != null)
Console.WriteLine("[{0}] was authenticated using [{1}], returned access token
[{2}] ",
id.Name,
id.AuthenticationType,
id.Token.ToString()
);
}
}
// using NTLM authentication
public class SSPIHelper
{
public static WindowsIdentity LogonUser(string userName, string password, string domain)
{
// need a full duplex stream - loopback is easiest way to get that
TcpListener tcpListener = new TcpListener(IPAddress.Loopback, 0);
tcpListener.Start();
WindowsIdentity id = null;
tcpListener.BeginAcceptTcpClient(delegate(IAsyncResult asyncResult)
{
using (NegotiateStream serverSide = new NegotiateStream(
tcpListener.EndAcceptTcpClient(asyncResult).GetStream()))
{
serverSide.AuthenticateAsServer(CredentialCache.DefaultNetworkCredentials,
ProtectionLevel.None, TokenImpersonationLevel.Impersonation);
id = (WindowsIdentity)serverSide.RemoteIdentity;
}
}, null);
using (NegotiateStream clientSide = new NegotiateStream(new
TcpClient(IPAddress.Loopback.ToString()
((IPEndPoint)tcpListener.LocalEndpoint).Port).GetStream()))
{
clientSide.AuthenticateAsClient(new NetworkCredential(userName, password,
domain),
"", ProtectionLevel.None, TokenImpersonationLevel.Impersonation);
}
return id;
}
}
Willy.
|