Home All Groups Group Topic Archive Search About

NegotiateStream delegation issue (or a bug?)

Author
11 May 2007 2:21 PM
DAXU
Hello,
I use NegotiateStream to test Kerberos and delegation in my windows
2003 test domain. My code is this:

private static WindowsIdentity LogonUserTCPListen(string userName,
string domain, string password)
        {
            // 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)
            {
                try
                {
                    using (NegotiateStream serverSide = new
NegotiateStream(

tcpListener.EndAcceptTcpClient(asyncResult).GetStream()))
                    {

serverSide.AuthenticateAsServer(CredentialCache.DefaultNetworkCredentials,
                             ProtectionLevel.EncryptAndSign,
TokenImpersonationLevel.Delegation);
                        id =
(WindowsIdentity)serverSide.RemoteIdentity;
                    }
                }
                catch
                { id = null; }
            }, null);

            using (NegotiateStream clientSide = new
NegotiateStream(new TcpClient("localhost",

((IPEndPoint)tcpListener.LocalEndpoint).Port).GetStream()))
            {
                clientSide.AuthenticateAsClient(new
NetworkCredential(userName, password, domain),
                     "RAM/lab2-srv-2k3-8.test-lab2.local",
ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Delegation);
            }
            return id;
        }


to use this function:
WindowsIdentity ID= LogonUserTCPListen("someuser, "test-lab2.local",
"8ik,7UJM");
using (WindowsImpersonationContext impersonationContext =
ID.Impersonate())
            {
                // ...
                try
                {
                    //not working
                    DirectoryInfo info = new DirectoryInfo(@"\
\10.10.10.7\home");
                    FileInfo[] infos = info.GetFiles();
                    MessageBox.Show(infos.Length.ToString());
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.GetBaseException().Message);
                    //works
                    DirectoryInfo info = new DirectoryInfo(@"\\lab2-
srv-2k3-7\home");
                    FileInfo[] infos = info.GetFiles();
                    MessageBox.Show(infos.Length.ToString());
                }
                finally
                {
                    impersonationContext.Undo();
                }

            }

>From debugging mode, I can see that windowsIdentity ID is using
Kerberos and delegation (which means that I have set SPN right). But
when I do impersonation, it can not access unc path "\
\10.10.10.7\home" which is on another machine. The error is access
denied. The most strangest thing is that if I put computer name there
instead of ip address in the UNC path, then it works.

Can someone give me some ideas?

Cheers,

Jerry

Author
11 May 2007 4:37 PM
Joe Kaplan
To access another service on a different machine using Kerberos, you can't
use the IP address because there won't be an SPN in AD that matches the IP
address, only the host name or DNS name.  That would likely explain why you
can't get Kerberos auth and thus can't delegate.  If you look on the remote
machine in the security event log (assuming logon audit events are enabled
for success and failure), you should see a logon for NT Authority\Anonymous
via NTLM.  That's usually what happens when SPNEGO can't negotiate to Kerb
and uses NTLM instead.

The SPNs associated with file shares are either cifs/xxxxx or HOST/xxxxx.
HOST is an alias for a variety of different services.  Those SPNs should be
set on the machine account for the server.  Essentially, you should be able
to use whatever names in your share path that have registered SPNs, which by
default are the plain host name and the server's DNS domain name.

Joe K.

--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net
--
<D***@HOTMAIL.COM> wrote in message
Show quoteHide quote
news:1178893306.728883.7240@l77g2000hsb.googlegroups.com...
> Hello,
> I use NegotiateStream to test Kerberos and delegation in my windows
> 2003 test domain. My code is this:
>
> private static WindowsIdentity LogonUserTCPListen(string userName,
> string domain, string password)
>        {
>            // 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)
>            {
>                try
>                {
>                    using (NegotiateStream serverSide = new
> NegotiateStream(
>
> tcpListener.EndAcceptTcpClient(asyncResult).GetStream()))
>                    {
>
> serverSide.AuthenticateAsServer(CredentialCache.DefaultNetworkCredentials,
>                             ProtectionLevel.EncryptAndSign,
> TokenImpersonationLevel.Delegation);
>                        id =
> (WindowsIdentity)serverSide.RemoteIdentity;
>                    }
>                }
>                catch
>                { id = null; }
>            }, null);
>
>            using (NegotiateStream clientSide = new
> NegotiateStream(new TcpClient("localhost",
>
> ((IPEndPoint)tcpListener.LocalEndpoint).Port).GetStream()))
>            {
>                clientSide.AuthenticateAsClient(new
> NetworkCredential(userName, password, domain),
>                     "RAM/lab2-srv-2k3-8.test-lab2.local",
> ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Delegation);
>            }
>            return id;
>        }
>
>
> to use this function:
> WindowsIdentity ID= LogonUserTCPListen("someuser, "test-lab2.local",
> "8ik,7UJM");
> using (WindowsImpersonationContext impersonationContext =
> ID.Impersonate())
>            {
>                // ...
>                try
>                {
>                    //not working
>                    DirectoryInfo info = new DirectoryInfo(@"\
> \10.10.10.7\home");
>                    FileInfo[] infos = info.GetFiles();
>                    MessageBox.Show(infos.Length.ToString());
>                }
>                catch (Exception ex)
>                {
>                    MessageBox.Show(ex.GetBaseException().Message);
>                    //works
>                    DirectoryInfo info = new DirectoryInfo(@"\\lab2-
> srv-2k3-7\home");
>                    FileInfo[] infos = info.GetFiles();
>                    MessageBox.Show(infos.Length.ToString());
>                }
>                finally
>                {
>                    impersonationContext.Undo();
>                }
>
>            }
>
>>From debugging mode, I can see that windowsIdentity ID is using
> Kerberos and delegation (which means that I have set SPN right). But
> when I do impersonation, it can not access unc path "\
> \10.10.10.7\home" which is on another machine. The error is access
> denied. The most strangest thing is that if I put computer name there
> instead of ip address in the UNC path, then it works.
>
> Can someone give me some ideas?
>
> Cheers,
>
> Jerry
>
Author
11 May 2007 6:52 PM
Dominick Baier
the

NegotiateStream.RemoteIdentity.AuthenticationType property tells you if you
are doing kerberos...

-----
Dominick Baier (http://www.leastprivilege.com)

Developing More Secure Microsoft ASP.NET 2.0 Applications (http://www.microsoft.com/mspress/books/9989.asp)

Show quoteHide quote
> To access another service on a different machine using Kerberos, you
> can't use the IP address because there won't be an SPN in AD that
> matches the IP address, only the host name or DNS name.  That would
> likely explain why you can't get Kerberos auth and thus can't
> delegate.  If you look on the remote machine in the security event log
> (assuming logon audit events are enabled for success and failure), you
> should see a logon for NT Authority\Anonymous via NTLM.  That's
> usually what happens when SPNEGO can't negotiate to Kerb and uses NTLM
> instead.
>
> The SPNs associated with file shares are either cifs/xxxxx or
> HOST/xxxxx. HOST is an alias for a variety of different services.
> Those SPNs should be set on the machine account for the server.
> Essentially, you should be able to use whatever names in your share
> path that have registered SPNs, which by default are the plain host
> name and the server's DNS domain name.
>
> Joe K.
>