mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
276 lines
5.6 KiB
276 lines
5.6 KiB
/************************************************************************
|
|
|
|
Copyright (c) 2000 - 2000 Microsoft Corporation
|
|
|
|
Module Name :
|
|
|
|
csd.h
|
|
|
|
Abstract :
|
|
|
|
Header file for SID and SECURITY_DESCRIPTOR abstraction.
|
|
|
|
Author :
|
|
|
|
Revision History :
|
|
|
|
***********************************************************************/
|
|
|
|
#pragma once
|
|
|
|
#include "qmgrlib.h"
|
|
|
|
HRESULT
|
|
IsGroupSid(
|
|
PSID sid,
|
|
BOOL * pGroup
|
|
);
|
|
|
|
PSID
|
|
CopyTokenSid(
|
|
HANDLE Token
|
|
);
|
|
|
|
HANDLE CopyThreadToken() throw( ComError );
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
class CSaveThreadToken
|
|
/*
|
|
|
|
A simple class to save and restore the active thread token.
|
|
This allows code to impersonate other users without having to save
|
|
and restore the old token.
|
|
|
|
The constructor throws a ComError if it cannot copy the previous thread token.
|
|
|
|
*/
|
|
{
|
|
public:
|
|
|
|
CSaveThreadToken() throw( ComError )
|
|
{
|
|
m_SavedToken = CopyThreadToken();
|
|
}
|
|
|
|
~CSaveThreadToken()
|
|
{
|
|
RTL_VERIFY( SetThreadToken( NULL, m_SavedToken ));
|
|
if (m_SavedToken)
|
|
{
|
|
RTL_VERIFY(CloseHandle( m_SavedToken ));
|
|
}
|
|
}
|
|
|
|
protected:
|
|
|
|
HANDLE m_SavedToken;
|
|
};
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
class CNestedImpersonation : protected CSaveThreadToken
|
|
/*
|
|
|
|
A class to impersonate a user. It saves the old impersonation token, if any,
|
|
during the constructor and restores it in the destructor.
|
|
|
|
Revert() restores the old thread token, unlike RevertToSelf() which
|
|
stops impersonating entirely.
|
|
|
|
Most member functions throw a ComError exception if an error occurs.
|
|
|
|
*/
|
|
{
|
|
public:
|
|
|
|
//
|
|
// Impersonate the COM client, using CoImpersonateClient.
|
|
//
|
|
CNestedImpersonation() throw( ComError );
|
|
|
|
//
|
|
// Impersonate a particular token. The token must remain valid for the object's lifetime.
|
|
//
|
|
CNestedImpersonation( HANDLE token ) throw( ComError );
|
|
|
|
//
|
|
// Impersonate a logged-on user by SID. g_Manager must be initialized for this to work.
|
|
//
|
|
CNestedImpersonation( SidHandle sid ) throw( ComError );
|
|
|
|
//
|
|
// This is for use with the COM-client constructor. COM defaults to IDENTIFY-level
|
|
// impersonation, but some of our code requires IMPERSONATE level. This function
|
|
// gets the COM client's SID and finds a matching token in our logged-on-users list.
|
|
// This becomes the new impersonation token.
|
|
//
|
|
void SwitchToLogonToken() throw( ComError );
|
|
|
|
//
|
|
// the destructor restores the previous impersonation context.
|
|
//
|
|
~CNestedImpersonation()
|
|
{
|
|
Revert();
|
|
|
|
if (m_ImpersonationToken && m_fDeleteToken)
|
|
{
|
|
CloseHandle( m_ImpersonationToken );
|
|
}
|
|
}
|
|
|
|
//
|
|
// Impersonates the new token.
|
|
//
|
|
void Impersonate() throw( ComError )
|
|
{
|
|
if (!m_fImpersonated)
|
|
{
|
|
if (!ImpersonateLoggedOnUser( m_ImpersonationToken ))
|
|
throw ComError( HRESULT_FROM_WIN32( GetLastError() ) );
|
|
m_fImpersonated = true;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Restores the old impersonation context.
|
|
//
|
|
void Revert()
|
|
{
|
|
if (m_fImpersonated)
|
|
{
|
|
RTL_VERIFY( SetThreadToken( NULL, m_SavedToken ));
|
|
m_fImpersonated = false;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Returns a copy of the SID associated with the impersonation token.
|
|
//
|
|
SidHandle CopySid() throw( ComError )
|
|
{
|
|
if (m_Sid.get() == NULL)
|
|
{
|
|
m_Sid = CopyTokenSid( m_ImpersonationToken );
|
|
}
|
|
|
|
return m_Sid;
|
|
}
|
|
|
|
//
|
|
// Returns the original impersonation token. Not a copy !
|
|
//
|
|
HANDLE QueryToken()
|
|
{
|
|
return m_ImpersonationToken;
|
|
}
|
|
|
|
//
|
|
// Gets the Terminal Services session ID.
|
|
//
|
|
DWORD GetSession() throw( ComError );
|
|
|
|
|
|
protected:
|
|
|
|
bool m_fDeleteToken;
|
|
bool m_fImpersonated;
|
|
|
|
HANDLE m_ImpersonationToken;
|
|
|
|
SidHandle m_Sid;
|
|
};
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
class CJobSecurityDescriptor
|
|
{
|
|
public:
|
|
|
|
CJobSecurityDescriptor( SidHandle sid );
|
|
|
|
~CJobSecurityDescriptor();
|
|
|
|
HRESULT Clone( CJobSecurityDescriptor ** );
|
|
|
|
inline HRESULT
|
|
AddAce(
|
|
PSID sid,
|
|
BOOL fGroupSid,
|
|
DWORD access
|
|
);
|
|
|
|
inline HRESULT
|
|
RemoveAce(
|
|
PSID sid,
|
|
BOOL fGroupSid
|
|
);
|
|
|
|
HRESULT
|
|
CheckTokenAccess(
|
|
HANDLE hToken,
|
|
DWORD RequestedAccess,
|
|
DWORD * pAllowedAccess,
|
|
BOOL * pSuccess
|
|
);
|
|
|
|
inline SidHandle GetOwnerSid()
|
|
{
|
|
return m_sdOwnerSid;
|
|
}
|
|
|
|
HRESULT Serialize( HANDLE hFile );
|
|
static CJobSecurityDescriptor * Unserialize( HANDLE hFile );
|
|
|
|
private:
|
|
|
|
HRESULT
|
|
CJobSecurityDescriptor::_ModifyAcl(
|
|
PSID sid,
|
|
BOOL fGroupSid,
|
|
DWORD access,
|
|
BOOL fAdd
|
|
);
|
|
|
|
CJobSecurityDescriptor( PSECURITY_DESCRIPTOR pSD,
|
|
SidHandle owner,
|
|
SidHandle group,
|
|
PACL pAcl
|
|
);
|
|
|
|
PSECURITY_DESCRIPTOR m_sd;
|
|
|
|
SidHandle m_sdOwnerSid;
|
|
SidHandle m_sdGroupSid;
|
|
PACL m_Dacl;
|
|
|
|
static GENERIC_MAPPING s_AccessMapping;
|
|
};
|
|
|
|
HRESULT
|
|
CJobSecurityDescriptor::AddAce(
|
|
PSID sid,
|
|
BOOL fGroupSid,
|
|
DWORD access
|
|
)
|
|
{
|
|
return _ModifyAcl( sid, fGroupSid, access, TRUE );
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CJobSecurityDescriptor::RemoveAce(
|
|
PSID sid,
|
|
BOOL fGroupSid
|
|
)
|
|
{
|
|
return _ModifyAcl( sid, fGroupSid, 0, FALSE );
|
|
}
|
|
|
|
HRESULT
|
|
CheckClientGroupMembership(
|
|
SidHandle group
|
|
);
|
|
|