Thursday, April 14, 2011

Windows下获取Logon Session信息

什么是LSA?什么是session?MSDN中的描述如下:




Local Security Authority



(LSA) A protected subsystem that authenticates and logs users onto the local system. LSA also maintains information about all aspects of local security on a system, collectively known as the Local Security Policy of the system.

(LSA) 一个判断用户登陆本系统时候的保护子系统。LSA也包含有关本系统中安全的所有方面,统称为本地安全策略的系统。

logon session



A logon session begins whenever a user logs on to a computer. All processes in a logon session have the same primary access token. The access token contains information about the security context of the logon session, including the user's SID, the logon identifier, and the logon SID.



当用户登陆计算机时,一个对应的logon session就开始了。一个logon session可以拥有多个进程,计算机上运行着的所有进程都属于一个唯一的session。怎么获取这些session和进程的相关信息呢?



LsaEnumerateLogonSessions函数可以获取已经存在的logon session identifiers (LUIDs) 和session的总数。



NTSTATUS NTAPI LsaEnumerateLogonSessions(

PULONG LogonSessionCount,

PLUID* LogonSessionList

);



当LogonSessionList不再需要时,需要调用LSAFreeReturnBuffer函数来释放所占用的内存。



看看刚才获取的LogonSessionList,数据类型为LUID。



typedef struct _LUID {

DWORD LowPart;

LONG HighPart;

} LUID, *PLUID;



为了通过LUID来获取详细的logon session信息,需要调用函数LsaGetLogonSessionData,调用者必须是拥有该session或者是本地的系统管理员。



NTSTATUS NTAPI LsaGetLogonSessionData(

PLUID LogonId,

PSECURITY_LOGON_SESSION_DATA* ppLogonSessionData

);



LsaGetLogonSessionData函数返回一个PSECURITY_LOGON_SESSION_DATA结构体。



typedef struct _SECURITY_LOGON_SESSION_DATA {

ULONG Size;

LUID LogonId;

LSA_UNICODE_STRING UserName;

LSA_UNICODE_STRING LogonDomain;

LSA_UNICODE_STRING AuthenticationPackage;

ULONG LogonType;

ULONG Session;

PSID Sid;

LARGE_INTEGER LogonTime;

LSA_UNICODE_STRING LogonServer;

LSA_UNICODE_STRING DnsDomainName;

LSA_UNICODE_STRING Upn;

} SECURITY_LOGON_SESSION_DATA, *PSECURITY_LOGON_SESSION_DATA;



其中包含了登陆标识(LogonId)、登陆的账号(UserName)、域(LogonDomain)、认证方式 (AuthenticationPackage)、登陆类型(LogonType)、会话ID(Session)、用户的Sid(Sid)、用户登陆时间 (LogonTime)等信息。



登陆类型(LogonType)是个枚举类型。



typedef enum _SECURITY_LOGON_TYPE {

Interactive = 2, // Interactively logged on (locally or remotely)

Network, // Accessing system via network

Batch, // Started via a batch queue

Service, // Service started by service controller

Proxy, // Proxy logon

Unlock, // Unlock workstation

NetworkCleartext, // Network logon with cleartext credentials

NewCredentials, // Clone caller, new default credentials

RemoteInteractive, // Remote, yet interactive. Terminal server

CachedInteractive, // Try cached credentials without hitting the net.

CachedRemoteInteractive, // Same as RemoteInteractive, this is used internally for auditing purpose

CachedUnlock // Cached Unlock workstation

} SECURITY_LOGON_TYPE, *PSECURITY_LOGON_TYPE;



用户的Sid(Sid)可以用ConvertSidToStringSid来转换成常见的SID格式字符串。



BOOL ConvertSidToStringSid(

PSID Sid,

LPTSTR* StringSid

);



这样,所有logon session的信息就获取到了。



更进一步的,用EnumProcesses函数枚举进程ID,OpenProcess获取每一个进程的句柄。在分别通过OpenProcessToken 和GetTokenInformation打开并获取进程的访问令牌信息。



BOOL OpenProcessToken(

HANDLE ProcessHandle,

DWORD DesiredAccess,

PHANDLE TokenHandle

);



BOOL GetTokenInformation(

HANDLE TokenHandle,

TOKEN_INFORMATION_CLASS TokenInformationClass,

LPVOID TokenInformation,

DWORD TokenInformationLength,

PDWORD ReturnLength

);



TokenInformationClass是个枚举类型,用来指明要获取的信息类型,这里用TokenStatistics即可。获取的信息在 TokenInformation中,数据类型为TOKEN_STATISTICS的结构体。



typedef struct _TOKEN_STATISTICS {

LUID TokenId;

LUID AuthenticationId;

LARGE_INTEGER ExpirationTime;

TOKEN_TYPE TokenType;

SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;

DWORD DynamicCharged;

DWORD DynamicAvailable;

DWORD GroupCount;

DWORD PrivilegeCount;

LUID ModifiedId;

} TOKEN_STATISTICS, *PTOKEN_STATISTICS;



其中LUID AuthenticationId如果和前面logon session的LUID一致,说明该进程的拥有者是相应的logon session。



通过类似的方法,能获取很多有用的信息。下面的程序是用这些API写的一个windows下获取logon session信息,并列举属于该session的进程。

How do I build a backyard shelter for the patio?

I don't want an octagonal or hexagonal gazebo. I just need to make a square shelter. No walls needed. Or, I could use a square gazebo. Something simple and to keep the sun and rain off.


If you know of any websites or books/videos than would be helpful on this specific topic, please let me know.



It seems to me that it would be very simple to do. Kind of like a canopy bed, but without the bed, and, with an angled canopy/roof so that the rain will run off. But, if there's a tried-and-true way to do it, I would appreciate the info. :)



The section of the patio that I want to cover is 10' x 10'. I will make it out of cedar.

Best Answer - Chosen by Voters


We built ours using a Sunset book that is sold at the Lowes, Perogals, Patio Covers and Gazebos. It gives very detailed instructions and material lists for a wide variety of different patio covers. We actually combined the plans of two different designs to meet our needs and it was very simple to build, but it took this husband and wife team a few more days to complete the project than the book indicated.
 
It is easy to do do.


Just be sure the pitch is 1" per foot, or in your case, 10" pitch down for proper run off.

Use rigid material, I now have fiberglass panels that I bought at Home Depot. I originally had a canvas type awning, but it did not last.

If you live in the North, be sure it is properly supported to withstand the weight of snow.

How to build a pergola

http://www.youtube.com/watch?v=tqx1y_oBkkw&feature=related

How to Build a Backyard Patio Roof

Adding a roof to your patio offers shade and protection from the elements, and you can easily build a flat roof on your backyard patio with a frame and metal sheeting. If you prefer to have an open roof, build it with a lattice. Check your local building codes and determine the depth for your structure posts and to obtain any required permits for building your patio roof.

* 1
Measure the patio area to be covered. Metal roof sheeting is sold in a variety of lengths and widths, so take the overall dimensions of your patio roof to your local home supply store and they will advise you of the number of panels you need in order to cover your patio. You will also need treated wood posts to support the metal roof, every 8 feet around the perimeter of your patio. Treated plywood will provide the base for your metal sheets. Treated wood is mildew and insect resistant, so you should always use it for any outdoor project. All the materials for your patio roof can be found at your local home improvement supply store.

* 2
Measure 8-feet increments and mark the location for your support post holes. Dig the holes in accordance with your local building codes and guidelines.

* 3
Stand the posts in the holes and brace them perpendicular to the ground with wood stakes. Mix quick-drying cement according to the manufacturer's instructions and pour it around the posts. Let the cement dry.

* 4
Build the frame to hold the metal sheets by attaching the 2 by 8 treated wood planks to the support posts around the perimeter of your patio. Build the cross support of your frame spanning the patio with the 2 by 12 treated wood planks, cut to size if your patio is not 12 feet wide. If it is wider than 12 feet, you will need another line of posts in place to support the frame.

* 5
Attach the treated plywood sheets to the frame, beginning in a corner and working your way outward. This step is not absolutely necessary, but it will make the structure of your patio roof stronger and create a more cohesive covering.

Attach the first metal sheet to one corner on top of the frame with wood screws. Cover your patio with the metal sheets. Cut the final metal sheets as needed to fit with your tin snips.