account, I should in fact be using its NativeGuid (i.e.
"Joubert" wrote:
> Hi Ken,
>
> "Ken Schaefer" wrote:
>
> >
> > "Joubert" <Joubert@discussions.microsoft.com> wrote in message
> > news:F6E36F51-8307-4B41-9C0C-05BBAFC22CEB@microsoft.com...
> > > Hi,
> > >
> > > We now want to support Windows Integrated auth so that the user does not
> > > have to enter a login name and password. One way to do this is to identify
> > > the user based on their domain\username. However, this can be spoofed, by
> > > setting up another computer so that the application is run under the same
> > > domain\username and then connecting to the datastore (since the user
> > > doesn't
> > > actually have to login to the domain in order to access the datastore,
> > > e.g.
> > > Access file on local drive or when connecting to SQL Server via TCP/IP).
> >
> > This can only be "spoofed" if the person setting up the application has both
> > the username *and* the corresponding password. If you have users that know
>
> No, you can spoof it without have the "real" password because you are not
> using the "real" Windows user account to identify yourself. Here's a sketch
> of the scenario:
>
> Setup
> =====
> Let's say the datastore is an MS Access database and is on a fileshare
> somewhere. In the authentication table the user George Smith is (literally)
> identified as STDOM\gsmith
> If George logs onto his network, Windows will return his domain\username as
> STDOM\gsmith (assuming he logged into that account). His Windows password is
> never stored in the application's datastore (the MS Access database).
> Remember we want the user not have to bother to enter their username /
> password - they've already done it in Windows.
>
> Naughty person
> ===========
> Now, let's say Jill Sander wants to impersonate George in order to get to
> information stored in the application datastore which only George can see
> because of his identity. She can setup a PC with the computer name "STDOM"
> (or on PC setup a Windows domain called "STDOM"). Further, she can create a
> user account called "gsmith" and choose whatever password she likes.
> She now simply logs into that account (Windows will now ID her as
> STDOM\gsmith) and launch the application. When she opens the datastore with
> the application it will do a match against the authentication table in the
> datastore and identify her has George Smith.
>
> Avoid the spoof
> ==========
> So, from the example above it appears as if simply using DOMAIN\username is
> not an adequate solution. And now we're back at my original e-mail.
> I am thinking of using the user's SID and store that in the authentication
> table in the datastore instead of teh DOMAIN\username. This should ensure it
> is in fact the SAME person and so avoid the possibility of impersonation.
>
> Is this assessment accurate?
>
> Regards
> Joubert
>
> > other user's passwords, then you're going to have a security issue no matter
> > what you do (for example, someone can obtain the SID knowing the username
> > and password)
> >
> > Cheers
> > Ken
> >
> > >
> > > The one solution I've come up with is to store the user's SID instead of
> > > domain\username, since according to the article at
> > >
http://www.microsoft.com/resources/documentation/WindowsServ/2003/standard/proddocs/en-us/Default.asp?url=/resources/documentation/WindowsServ/2003/standard/proddocs/en-us/sag_ADintro_12.asp
> > > this is guaranteed to be unique and is in fact the method Windows uses to
> > > refer to user accounts.
> > >
> > > Is my assessment of how to implement Windows Integrated auth correct?
> > >
> > > I have even written a short C# application that retrieves the SID for a
> > > user
> > > account (I include the source below).
> > >
> > > using System;
> > > using System.Text;
> > > using System.Diagnostics;
> > > using System.DirectoryServices;
> > >
> > > namespace GetWindowsAuthName
> > > {
> > > /// <summary>
> > > /// Summary description for Class1.
> > > /// </summary>
> > > class Application
> > > {
> > > /// <summary>
> > > /// The main entry point for the application.
> > > /// </summary>
> > > [STAThread]
> > > static void Main(string[] args)
> > > {
> > > PrintUsageInstructions();
> > >
> > > System.Security.Principal.WindowsIdentity identity =
> > > System.Security.Principal.WindowsIdentity.GetCurrent();
> > > string username;
> > >
> > > if (args.Length > 0)
> > > {
> > > username = args[0];
> > > }
> > > else
> > > {
> > >
> > > username = identity.Name;
> > > }
> > >
> > > PrintSidInformation(username);
> > >
> > > Console.WriteLine();
> > > Console.Write("Press <ENTER> to continue...");
> > > Console.ReadLine();
> > > }
> > >
> > > private static void PrintSidInformation(string username)
> > > {
> > > Console.WriteLine("Getting SID for: " + username);
> > > Console.WriteLine("SID = " + GetSid(username));
> > > }
> > >
> > > private static void PrintUsageInstructions()
> > > {
> > > Console.WriteLine("Usage instructions:");
> > > Console.WriteLine(@"GetWinAuthDetails [username@domain]
> > > [domain\username]");
> > > Console.WriteLine();
> > > }
> > >
> > > private static string GetSid(string strLogin)
> > > {
> > > string str = "";
> > > // Parse the string to check if domain name is present.
> > > int idx = strLogin.IndexOf('\\');
> > > if (idx == -1)
> > > {
> > > idx = strLogin.IndexOf('@');
> > > }
> > >
> > > string strDomain;
> > > string strName;
> > >
> > > if (idx != -1)
> > > {
> > > strDomain = strLogin.Substring(0, idx);
> > > strName = strLogin.Substring(idx+1);
> > > }
> > > else
> > > {
> > > strDomain = Environment.MachineName;
> > > strName = strLogin;
> > > }
> > >
> > > Debug.WriteLine("Domain: " + strDomain);
> > > Debug.WriteLine("Username: " + strName);
> > >
> > >
> > > DirectoryEntry obDirEntry = null;
> > > try
> > > {
> > > Int64 iBigVal = 5;
> > > Byte[] bigArr = BitConverter.GetBytes(iBigVal);
> > > obDirEntry = new DirectoryEntry("WinNT://" + strDomain + "/" + strName);
> > > System.DirectoryServices.PropertyCollection coll = obDirEntry.Properties;
> > > object obVal = coll["objectSid"].Value;
> > > if (null != obVal)
> > > {
> > > str = ConvertByteToStringSid((Byte[])obVal);
> > > }
> > >
> > > }
> > > catch (Exception ex)
> > > {
> > > str = "";
> > > Debug.Write(ex.Message);
> > > }
> > > return str;
> > > }
> > >
> > > private static string ConvertByteToStringSid(Byte[] sidBytes)
> > > {
> > > short sSubAuthorityCount = 0;
> > > StringBuilder strSid = new StringBuilder();
> > > strSid.Append("S-");
> > > try