|
security
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Impersonating when creating a process from inside a SQL Server AssemblyThis 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 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. -- Show quoteHide quoteJoe Kaplan-MS MVP Directory Services Programming Co-author of "The .NET Developer's Guide to Directory Services Programming" http://www.directoryprogramming.net -- "Keith" <ke***@alh.com> wrote in message news:%23miCQt7HHHA.1044@TK2MSFTNGP02.phx.gbl... > 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,
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 Show quoteHide quote "Joe Kaplan" <joseph.e.kap***@removethis.accenture.com> wrote in message news:e26Rr67HHHA.420@TK2MSFTNGP02.phx.gbl... > 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. > > -- > Joe Kaplan-MS MVP Directory Services Programming > Co-author of "The .NET Developer's Guide to Directory Services > Programming" > http://www.directoryprogramming.net > -- > "Keith" <ke***@alh.com> wrote in message > news:%23miCQt7HHHA.1044@TK2MSFTNGP02.phx.gbl... >> 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 >> > > 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. -- Show quoteHide quoteJoe Kaplan-MS MVP Directory Services Programming Co-author of "The .NET Developer's Guide to Directory Services Programming" http://www.directoryprogramming.net -- "Keith" <ke***@alh.com> wrote in message news:euNsMo9HHHA.960@TK2MSFTNGP04.phx.gbl... > 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 > > "Joe Kaplan" <joseph.e.kap***@removethis.accenture.com> wrote in message > news:e26Rr67HHHA.420@TK2MSFTNGP02.phx.gbl... >> 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. >> >> -- >> Joe Kaplan-MS MVP Directory Services Programming >> Co-author of "The .NET Developer's Guide to Directory Services >> Programming" >> http://www.directoryprogramming.net >> -- >> "Keith" <ke***@alh.com> wrote in message >> news:%23miCQt7HHHA.1044@TK2MSFTNGP02.phx.gbl... >>> 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 >>> >> >> > > 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) Show quoteHide quote > 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. > 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) Show quoteHide quote > 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. > 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 Show quoteHide quote "Keith" <ke***@alh.com> wrote in message news:euNsMo9HHHA.960@TK2MSFTNGP04.phx.gbl... > 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 > > "Joe Kaplan" <joseph.e.kap***@removethis.accenture.com> wrote in message > news:e26Rr67HHHA.420@TK2MSFTNGP02.phx.gbl... >> 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. >> >> -- >> Joe Kaplan-MS MVP Directory Services Programming >> Co-author of "The .NET Developer's Guide to Directory Services >> Programming" >> http://www.directoryprogramming.net >> -- >> "Keith" <ke***@alh.com> wrote in message >> news:%23miCQt7HHHA.1044@TK2MSFTNGP02.phx.gbl... >>> 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 >>> >> >> > > 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! -- Show quoteHide quoteJoe Kaplan-MS MVP Directory Services Programming Co-author of "The .NET Developer's Guide to Directory Services Programming" http://www.directoryprogramming.net -- "Keith" <ke***@alh.com> wrote in message news:%23x%23yVl%23HHHA.3268@TK2MSFTNGP04.phx.gbl... > 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 > > "Keith" <ke***@alh.com> wrote in message > news:euNsMo9HHHA.960@TK2MSFTNGP04.phx.gbl... >> 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 >> >> "Joe Kaplan" <joseph.e.kap***@removethis.accenture.com> wrote in message >> news:e26Rr67HHHA.420@TK2MSFTNGP02.phx.gbl... >>> 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. >>> >>> -- >>> Joe Kaplan-MS MVP Directory Services Programming >>> Co-author of "The .NET Developer's Guide to Directory Services >>> Programming" >>> http://www.directoryprogramming.net >>> -- >>> "Keith" <ke***@alh.com> wrote in message >>> news:%23miCQt7HHHA.1044@TK2MSFTNGP02.phx.gbl... >>>> 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 >>>> >>> >>> >> >> > > 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
GetOwner and IdentityNotMappedException
regarding retrival of server certificate Permissions on Event Log? SecurityException: Request failed in LoadControl Config Info in DMZ Thread.CurrentPrincipal still returns GenericPrincipal Extract Public Key From certificate and RSACryptoServiceProvider How to track app focus in Vista? Making web services secure Version of free virus protection from MSN. |
|||||||||||||||||||||||