Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / Security / December 2006

Tip: Looking for answers? Try searching our database.

Impersonating when creating a process from inside a SQL Server Assembly

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Keith - 14 Dec 2006 19:58 GMT
Hello,

This is my situation:  I'm trying to impersonate a different user when
creating a process from inside a .NET assembly on SQL Server.  Basically the
flow looks like this:

stored procedure->static C# function in Assembly->Process created in
Asembly->External Application

This works, but the external app fails because the current WindowsIdentity
is NT AUTHORITY/WINDOWS SERVICE. ; it needs to be someone else.

Now, when you are inside a .NET assembly in SQL Server, you have access to
an object called SqlContext, and it contains (among other things) a
WindowsIdentity object that is the login user who called the stored
procedure in the first place.  This is the user I want to impersonate but I
can't seem to get it to work.

In other postings I've read that you can't get this to work with a Process -
apparently the process still inherits the Principal token and but the
Impersonation token - but it DOES work with Threads.  So I thought I'd spawn
a new Thread with the correct identity and launch my process from inside.
To test the Thread idea I used:

ParameterizedThreadStart pts = new
ParameterizedThreadStart(someThreadFunction);
Thread thread = new Thread(pts);

WindowsIdentity contextID = SqlContext.WindowsIdentity;
using (WindowsImpersonationContext wip = contextID.Impersonate())
{
  thread.Start(test);
  while (thread.ThreadState == System.Threading.ThreadState.Running) { }
  wip.Undo();
}

But inside the Thread function (someThreadFunction) the
WindowsIdentity.GetCurrent() still returns NT AUTHORITY/WINDOWS SERVICE.

Am I going about this all wrong?  Is this even possible?

Any advice/suggestions appreciated!

Keith
Joe Kaplan - 14 Dec 2006 20:30 GMT
It doesn't work this way.  Processes created with the Process class inherit
the process token, not the impersonated token.  The Process class allows you
to specify credentials in .NET 2.0, but I don't know if that would help you
in your use case, as you don't have the user's password.

You could try calling CreateProcessWithTokenW, but you'd probably also need
to call DuplicateTokenEx to convert the impersonation token in the
WindowsIdentity into a primary token.

Joe K.

Signature

Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net
--

> Hello,
>
[quoted text clipped - 40 lines]
>
> Keith
Keith - 14 Dec 2006 23:38 GMT
Joe,

Thanks for the reply.  I'm aware that you can't create processes this way,
but I've seen posts in this ng where they claim you can create a new Thread
that way but I can't get that to work either.  Inside the thread the current
WindowsIdentity is still WINDOWS SERVICE.

Can you confirm that creating a new Thread with an impersonated
WindowsIdentity should work?  If it does, would creating a new process
inside that thread have the correct WindowsIdentity?

k

> It doesn't work this way.  Processes created with the Process class
> inherit the process token, not the impersonated token.  The Process class
[quoted text clipped - 52 lines]
>>
>> Keith
Joe Kaplan - 15 Dec 2006 00:29 GMT
Maybe I'm just misremembering and only the ThreadPool does this
automatically now?  I'm sure Dominick or someone will correct me.

In any case, if you just spin up a thread with the Thread class, you should
be able to impersonate by passing in the WindowsIdentity in the state for
the thread and then just impersonating it manually.  It is a little
annoying, but should work.

Regardless, creating a new Process will always use the process identity
unless you start the process with explicit credentials or perhaps attempt
that pinvoke technique I mentioned.

Joe K.

Signature

Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net
--

> Joe,
>
[quoted text clipped - 65 lines]
>>>
>>> Keith
Dominick Baier - 15 Dec 2006 07:30 GMT
in .NET 2.0 impersonation tokens are generally propagated to new threads
(regardless of how you create the thread).

That said - Sql Server may behave different (as does ASP.NET see http://www.leastprivilege.com/WhatIsAspnetconfig.aspx)

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

> Maybe I'm just misremembering and only the ThreadPool does this
> automatically now?  I'm sure Dominick or someone will correct me.
[quoted text clipped - 9 lines]
>
> Joe K.
Dominick Baier - 15 Dec 2006 07:31 GMT
You may also have a look at System.Threading.ExecutionContext...

But be aware that some things are just not allowed/supported in SQL Server...
-----
Dominick Baier (http://www.leastprivilege.com)

> Maybe I'm just misremembering and only the ThreadPool does this
> automatically now?  I'm sure Dominick or someone will correct me.
[quoted text clipped - 9 lines]
>
> Joe K.
Keith - 15 Dec 2006 01:28 GMT
Joe,

I found this article and if you substitute SQL Server for IIS/ASP.NET it
gets pretty close:

http://support.microsoft.com/default.aspx?scid=kb;EN-US;889251

Sadly, I can't get this to work either; the DuplicateTokenEx always fails if
I user the SqContext.WindowsIdentity.Token of the login user.  I added the
required user rights (Replace a process level token) at the local and domain
level, but DuplicateTokenEx still returns 0 (as does LastError).  It does
work if I use CurrentUser() which is WINDOWS SERVICE.

Any ideas how I might be able to find out why the DuplicateTokenEx is
failing?

Keith

> Joe,
>
[quoted text clipped - 65 lines]
>>>
>>> Keith
Joe Kaplan - 15 Dec 2006 02:37 GMT
I don't really have any idea on this one, but GetLastError should work.  I'd
suggest trying to use the Marshal.GetLastWin32Error and make sure you call
that right after you call DuplicateTokenEx to ensure that nothing clears
that state.  Maybe that will help.

This might be a question you want to try out in the PlatformSDK.Security
newsgroup too.

Good luck!

Signature

Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net
--

> Joe,
>
[quoted text clipped - 86 lines]
>>>>
>>>> Keith
Andy - 15 Dec 2006 18:12 GMT
Don't know much about security, but just a thought if you are
experiencing failures for many examples that should have worked...

If you are using Active Directory, do you have Kerbros security turned
on (it is shipped off by default)?   Will turning it on make a
difference as to whether the primary or the impersonation token is
passed?  I understand Kerbros will allow an impersonation token to make
multiple hops while windows security does not.

Andy

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.