antiduh / nsspi

A C# / .Net interface to the Win32 SSPI authentication API

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Issues (reading registry and other stuff) after impersonation (using NTLM)

ggo98 opened this issue · comments

commented

Hello,

I have tried nsspi, and it's a very nice component.
However I'm having issues after impersonation:

  • with special folders (MyDocuments)
  • trying to read registry.
  • The existing code which writes a file does not work either.

The server is running under a user profile (Someuser2) which:

  • is part of the Users group.
  • has the "Impersonate a Client AfterAuthentication" User Right (SeImpersonatePrivilege).
    I suppose the problem is with Someuser2.
    I hope you can point me to the right direction...

The client is running under another profile.

The tests are performed in the same workgroup (no domain), and the problem occurs when the client and the server run on the same machine (Win 8.1) or on 2 different machines (server=Win8.1,client=Win2016).

Some stuff works, but:

  • I have added serveral lines of code in ServerForm.impersonateButton_Click() to read the registry and it does not work (exceptions thrown).

  • The code which is is originally in ServerForm.impersonateButton_Click() to write a file does not work anymore either.

  • Of course I did not change anything else in the code.

      private void impersonateButton_Click(object sender, EventArgs e)
      {
      	ImpersonationHandle handle;
    
      	// Get the MyDocuments folder before impersonation: WORKS.
      	Console.WriteLine("MyDoc BEFORE impersonation=" + Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments));
    
      	using (handle = this.serverContext.ImpersonateClient())
      	{
      		// Get the current UserName AFTER impersonation: WORKS.
      		Console.WriteLine("Starting impersonation: " + Environment.UserName + Environment.NewLine);
    
      		// Get the MyDocuments folder AFTER impersonation: *** DOES NOT WORK ***.
      		// (an empty string is returned)
      		string s = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
      		Console.WriteLine("MyDoc AFTER impersonation=" + s);
    
      		MessageBox.Show("Starting impersonation: " + Environment.UserName);
      		MessageBox.Show("MyDoc AFTER impersonation=" + Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)); // EMPTY
    
      		try
      		{
      			Console.WriteLine("GetVal");
    
      			// *** DOES NOT WORK (Exceptions) ***
      			// (Details about the exceptions below)
      			var data = Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion",
      				"CommonFilesDir", "Not found");
    
      			Console.WriteLine(data.ToString());
      			int a = 123;
      		}
      		catch (Exception ex)
      		{
      			Console.WriteLine("EX: " + ex.ToString());
      			Console.WriteLine(ex.StackTrace);
      			ex = ex;
      			int a = 123;
      		}
    
      		try
      		{
      			// *** DOES NOT WORK (Exception) ***
      			// (Detail about the exceptions below)
      			FileStream stream = File.Create(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + @"\test.txt");
      			StreamWriter writer = new StreamWriter(stream, Encoding.UTF8);
    
      			writer.WriteLine("Hello world.");
    
      			writer.Close();
      			stream.Close();
      		}
      		catch (Exception ex)
      		{
      			Console.WriteLine("EX2: " + ex.ToString());
      			Console.WriteLine(ex.StackTrace);
      			ex = ex;
      			int a = 123;
      		}
      	}
    

`
Here are the details I could get with the Visual Studio debugger:

System.ArgumentException occurred
HResult=-2147024809
Message=Unknown error "1346".
Source=mscorlib
StackTrace:
at System.Diagnostics.Tracing.EventProvider.Register(Guid providerGuid)
InnerException:

(1346 is Either a required impersonation level was not provided, or the provided impersonation level is invalid.)

System.Security.SecurityException occurred
HResult=-2146233078
Message=Requested registry access is not allowed.
Source=mscorlib
StackTrace:
at System.ThrowHelper.ThrowSecurityException(ExceptionResource resource)
InnerException:

(-2146233078 = 0x8013150A = COR_E_SECURITY)

Here are the details in the console:

TestServer
Server: Received ClientToken
Server: Sent ServerToken
Server: Received ClientToken
Server: Sent ServerToken
MyDoc BEFORE impersonation=C:\Users\Someuser2\Documents
Starting impersonation: ggo

MyDoc AFTER impersonation=
GetVal
*** REGISTRY access ***
EX: System.Security.SecurityException: Requested registry access is not allowed.
at System.ThrowHelper.ThrowSecurityException(ExceptionResource resource)
at Microsoft.Win32.RegistryKey.OpenSubKey(String name, Boolean writable)
at Microsoft.Win32.Registry.GetValue(String keyName, String valueName, Object
defaultValue)
at TestServer.ServerForm.impersonateButton_Click(Object sender, EventArgs e)
The Zone of the assembly that failed was:
MyComputer
System.Security.SecurityException
at System.ThrowHelper.ThrowSecurityException(ExceptionResource resource)
at Microsoft.Win32.RegistryKey.OpenSubKey(String name, Boolean writable)
at Microsoft.Win32.Registry.GetValue(String keyName, String valueName, Object
defaultValue)
at TestServer.ServerForm.impersonateButton_Click(Object sender, EventArgs e)

*** File creation access ***
EX2: System.IO.IOException: Unknown error "1346".
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, I
nt32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions o
ptions, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolea
n useLongPath, Boolean checkHost)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access,
FileShare share, Int32 bufferSize)
at System.IO.File.Create(String path)
at TestServer.ServerForm.impersonateButton_Click(Object sender, EventArgs e)
System.IO.IOException
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, I
nt32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions o
ptions, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolea
n useLongPath, Boolean checkHost)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access,
FileShare share, Int32 bufferSize)
at System.IO.File.Create(String path)
at TestServer.ServerForm.impersonateButton_Click(Object sender, EventArgs e)

Thank you very much,
best regards,
Olivier gg.

I believe that you need 'Act as part of operating system' privilege too. Give this permission too and check it again.

commented

Thank you for the suggestion.
Unfortunately it didn't help. I have even restarted the system just in case, but it's still not working.
I have noticed that it works when I run the server example as SYSTEM, but I still can't figure out which permission is missing for Someuser2...

Is it working if the Someuser2 member of the 'Administrators' group?

Try to give the 'Create global objects' privileges too and try it again.

commented

It didn't work with the 'Create global objects' privilege,
but adding Someuser2 to the 'Administrators' group did work!
Thank you.
I guess I have to figure out what are the user rights differences between the 'Administrators' group and the regular 'Users' group regarding impersonation...
Thank again.