1 /// <summary>
2 /// Return codes for the validate user credentials function
3 /// </summary>
4 public enum ValidateUserCredentialsReturnCodes
5 {
6 /// <summary>
7 /// user name and password provided were authenticated successfully
8 /// </summary>
9 SUCCESS = 0,
10 /// <summary>
11 /// Bad user name or password was provided
12 /// </summary>
13 ERROR_BAD_USERNAME_OR_PASSWORD = 1,
14 /// <summary>
15 /// An unknown error occurred
16 /// </summary>
17 UNKNOWN_ERROR = 99
18 }
19
20 /// <summary>
21 /// Validate a user's credentials against active directory.
22 /// </summary>
23 /// <param name="DomainName">string. The user's domain name. Example "AMERICAS"</param>
24 /// <param name="UserName">string. User name. Example "kevin_shuma"</param>
25 /// <param name="Password">string. The user's password.</param>
26 /// <returns>bool. True = authentication success, False = authentication failure.</returns>
27 public static ValidateUserCredentialsReturnCodes
28 ValidateUserCredentials(string DomainName, string UserName, string Password)
29 {
30 try
31 {
32 // create a server-side stream that can be authenticated against
33 // create a full duplex stream using the loopback adapter
34 TcpListener TcpListener = new TcpListener(IPAddress.Loopback, 0);
35 TcpListener.Start();
36 WindowsIdentity Id = null;
37 bool AnswerReceived = false;
38 TcpListener.BeginAcceptTcpClient(delegate(IAsyncResult AsyncResult)
39 {
40 using (NegotiateStream ServerSide = new NegotiateStream(
41 TcpListener.EndAcceptTcpClient(AsyncResult).GetStream()))
42 {
43 try
44 {
45 ServerSide.AuthenticateAsServer(
46 CredentialCache.DefaultNetworkCredentials,
47 ProtectionLevel.None,
48 TokenImpersonationLevel.Impersonation);
49 Id = (WindowsIdentity)ServerSide.RemoteIdentity;
50 }
51 catch
52 {
53 Id = null;
54 }
55 AnswerReceived = true;
56 }
57 }, null);
58
59 // try to create a connection to the server-side stream
60 // and use the supplied credentials for authentication
61 using (NegotiateStream ClientSide =
62 new NegotiateStream(new TcpClient(IPAddress.Loopback.ToString(),
63 ((IPEndPoint)TcpListener.LocalEndpoint).Port).GetStream()))
64 {
65 ClientSide.AuthenticateAsClient(
66 new NetworkCredential(UserName, Password, DomainName),
67 string.Empty,
68 ProtectionLevel.None,
69 TokenImpersonationLevel.Impersonation);
70 }
71
72 // if the code executes before the connection on the server-side
73 // replies, a false NULL is returned. wait until an answer
74 // is received (up to the timeout value) before continuing
75 const int WAIT_INTERVAL = 50; // MS to wait between polling
76 const int MAX_WAIT_TIME = 2000; // max MS to wait
77 for (int i = 0; i < MAX_WAIT_TIME / WAIT_INTERVAL; i++)
78 {
79 if (AnswerReceived)
80 break;
81 Thread.Sleep(WAIT_INTERVAL);
82 }
83
84 if (Id != null) // not null = logon okay
85 return ValidateUserCredentialsReturnCodes.SUCCESS;
86 else // null = logon failed
87 return ValidateUserCredentialsReturnCodes.ERROR_BAD_USERNAME_OR_PASSWORD;
88 }
89 catch (Exception ex)
90 {
91 Logging.LogException(MethodBase.GetCurrentMethod(), ref ex);
92 return ValidateUserCredentialsReturnCodes.UNKNOWN_ERROR;
93 }
94 }