Creating Processes: Sessions and Integrity Levels

Changing Integrity Levels 

There are times when you might want to create a process with a different integrity level than your current process.  For example, you might want to launch IE at medium or low integrity from an installer that is running at high integrity.  If you just call CreateProcess, then IE would be launched at high integrity instead of low, and would not run in protected mode.

There are plenty of samples on the net showing how to do this, for example:  http://www.codeproject.com/KB/vista-security/createprocessexplorerleve.aspx?display=Print

The commonly shown technique is simple:  Get the token that is used by explorer.exe (in the current session), and use CreateProcessWithTokenW to create the new process using the explorer.exe security token.  Note that the key to these techniques is to use CreateProcessWithTokenW, and not CreateProcessAsUser because user accounts do not typically have the necessary privileges to call CreateProcessAsUser.

Creating Processes from Services 

There are other times when you might want to create a process on behalf of a user in a particular session from a service (running as SYSTEM).  An example of this scenario would be a broker service for an IE extension, where you may want to execute the process under an administrative account, but in the same session as a particular user.

You might think you could use the same technique as above where you just get the token from the process you want to emulate (e.g. winlogon.exe to execute as SYSTEM), modify the token to use the desired session ID, and use CreateProcessWithTokenW to create the process.  However, you would find that for reasons unknown, you cannot use CreateProcessWithTokenW to create a process in a different session (as revealed by MSFT here:  http://social.msdn.microsoft.com/Forums/en-US/windowssecurity/thread/f38b0dd4-d69f-4b7e-b85c-af40a1425636/)

In this case you will need to use CreateProcessAsUser, which you can use if you are running under the SYSTEM account.

Which Session to Use? 

A frequent, if troubling, question I've seen asked is how to get a handle on the "current" session so a process can be created from a service in the "correct" session and not in the service session.  Perhaps more troubling is the frequent display of examples of how to get the "active" session.  Even on reputable sites like codeproject.com.

Here is an entertaining exerpt from Raymond Chen's blog on the topic:

Original source: http://blogs.msdn.com/oldnewthing/archive/2006/08/22/712677.aspx

How do I impersonate the currently logged-on user?"

"Which user? There can be more than one. "

"I want the one on the desktop."

"They all have their own desktop."

"I want the one on the current desktop."

"What do you mean by 'the' current desktop? There is one current desktop for each user."

"I want the desktop I should display my UI on."

"Your question has become circular. You want to display your UI on the desktop that your UI should be displayed on."  

The answer is:  You have to know which session to create a process in.  If you are writing a broker service, then your communication with your service should include the session from which the original request is being made so the service knows where to display the UI.  And the service can then use that to create the new process in the correct session.

Putting it all together

To meet all of the needs above, I created a simple helper function that looks like this:

BOOL ExecuteWithProcessTokenW(

    DWORD dwSessionId,

    LPCWSTR pwszCmdLine,

    LPCWSTR pwszProcessName,

    PROCESS_INFORMATION *pi);

To make sure this function will work from either a service or a user account and create the process in the correct session, this function first attempts to use CreateProcessAsUser (which works from the SYSTEM account and can specify a different session id), and then falls back to CreateProcessWithTokenW if that fails (which works from a standard user account).

hope that helps. 

Spring Session 是一个用于管理 Web 应用会话的框架,它提供了一种将会话信息存储在外部存储介质中的方法,以便多个应用程序实例可以共享相同的会话数据。在 Spring Session 中,会话的过期时间是通过在 Redis/数据库等外部存储介质中设置相应的 key 的过期时间来实现的。 具体来说,在 Spring Session 中,会话数据被存储在外部存储介质中的某个 key 下。而 key 的过期时间是由外部存储介质来维护的。例如,在 Redis 中,可以使用 `EXPIRE` 命令来设置 key 的过期时间;在数据库中,可以使用类似 `DELETE FROM session WHERE expire_time < NOW()` 的 SQL 语句来删除已经过期的会话数据。 在 Spring Session 中,会话过期时间的配置是在 `spring:session:sessions:expires` 属性中进行的。这个属性可以通过 Spring Boot 的配置文件或者通过 Java 代码来配置。具体来说,当 `spring:session:sessions:expires` 属性被配置为一个正整数时,表示会话的过期时间为该正整数所表示的秒数。当这个属性被配置为 `-1` 时,表示会话永不过期。 在 Spring Session 的源码中,会话过期时间的处理是在 `org.springframework.session.data.redis.RedisOperationsSessionRepository` 类中完成的。具体来说,在 `RedisOperationsSessionRepository` 类中,会话数据被存储在 Redis 中的一个 key 下,而 key 的过期时间是通过调用 `RedisOperations#expire` 方法来设置的。在 `RedisOperationsSessionRepository` 类的 `afterPropertiesSet` 方法中,会根据 `spring:session:sessions:expires` 属性的值来设置 Redis 中 key 的过期时间。如果 `spring:session:sessions:expires` 属性的值为正整数,则会将 Redis 中 key 的过期时间设置为该正整数所表示的秒数;如果 `spring:session:sessions:expires` 属性的值为 `-1`,则会将 Redis 中 key 的过期时间设置为 0,表示该 key 永不过期。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值