263 lines
5.4 KiB
C++
263 lines
5.4 KiB
C++
/*++
|
|
|
|
Copyright (c) 2001 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
secutils.cpp
|
|
|
|
Abstract:
|
|
The utility functions for the shims.
|
|
|
|
History:
|
|
|
|
02/09/2001 maonis Created
|
|
08/14/2001 robkenny Moved code inside the ShimLib namespace.
|
|
|
|
--*/
|
|
|
|
#include "secutils.h"
|
|
#include "StrSafe.h"
|
|
|
|
namespace ShimLib
|
|
{
|
|
/*++
|
|
|
|
Function Description:
|
|
|
|
Determine if the log on user is a member of the group.
|
|
|
|
Arguments:
|
|
|
|
IN dwGroup - specify the alias of the group.
|
|
OUT pfIsMember - TRUE if it's a member, FALSE if not.
|
|
|
|
Return Value:
|
|
|
|
TRUE - we successfully determined if it's a member.
|
|
FALSE otherwise.
|
|
|
|
DevNote:
|
|
|
|
We are assuming the calling thread is not impersonating.
|
|
|
|
History:
|
|
|
|
02/12/2001 maonis Created
|
|
|
|
--*/
|
|
|
|
BOOL
|
|
SearchGroupForSID(
|
|
DWORD dwGroup,
|
|
BOOL* pfIsMember
|
|
)
|
|
{
|
|
PSID pSID = NULL;
|
|
SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;
|
|
BOOL fRes = TRUE;
|
|
|
|
if (!AllocateAndInitializeSid(
|
|
&SIDAuth,
|
|
2,
|
|
SECURITY_BUILTIN_DOMAIN_RID,
|
|
dwGroup,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
&pSID))
|
|
{
|
|
DPF("SecurityUtils", eDbgLevelError, "[SearchGroupForSID] AllocateAndInitializeSid failed %d", GetLastError());
|
|
return FALSE;
|
|
}
|
|
|
|
if (!CheckTokenMembership(NULL, pSID, pfIsMember))
|
|
{
|
|
DPF("SecurityUtils", eDbgLevelError, "[SearchGroupForSID] CheckTokenMembership failed: %d", GetLastError());
|
|
fRes = FALSE;
|
|
}
|
|
|
|
FreeSid(pSID);
|
|
|
|
return fRes;
|
|
}
|
|
|
|
/*++
|
|
|
|
Function Description:
|
|
|
|
Determine if we should shim this app or not.
|
|
|
|
If the user is
|
|
1) a member of the Users and
|
|
2) not a member of the Administrators group and
|
|
3) not a member of the Power Users group and
|
|
3) not a member of the Guest group
|
|
|
|
we'll apply the shim.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
TRUE - we should apply the shim.
|
|
FALSE otherwise.
|
|
|
|
History:
|
|
|
|
02/12/2001 maonis Created
|
|
|
|
--*/
|
|
|
|
BOOL
|
|
ShouldApplyShim()
|
|
{
|
|
BOOL fIsUser, fIsAdmin, fIsPowerUser, fIsGuest;
|
|
|
|
if (!SearchGroupForSID(DOMAIN_ALIAS_RID_USERS, &fIsUser) ||
|
|
!SearchGroupForSID(DOMAIN_ALIAS_RID_ADMINS, &fIsAdmin) ||
|
|
!SearchGroupForSID(DOMAIN_ALIAS_RID_POWER_USERS, &fIsPowerUser) ||
|
|
!SearchGroupForSID(DOMAIN_ALIAS_RID_GUESTS, &fIsGuest))
|
|
{
|
|
//
|
|
// Don't do anything if we are not sure.
|
|
//
|
|
return FALSE;
|
|
}
|
|
|
|
return (fIsUser && !fIsPowerUser && !fIsAdmin && !fIsGuest);
|
|
}
|
|
|
|
|
|
// The GENERIC_MAPPING from generic file access rights to specific and standard
|
|
// access types.
|
|
static GENERIC_MAPPING s_gmFile =
|
|
{
|
|
FILE_GENERIC_READ,
|
|
FILE_GENERIC_WRITE,
|
|
FILE_GENERIC_EXECUTE,
|
|
FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE
|
|
};
|
|
|
|
/*++
|
|
|
|
Function Description:
|
|
|
|
Given the creation dispositon and the desired access when calling
|
|
CreateFile, we determine if the caller is requesting write access.
|
|
|
|
This is specific for files.
|
|
|
|
Arguments:
|
|
|
|
IN pszObject - name of the file or directory.
|
|
OUT pam - points to the access mask of the user to this object.
|
|
|
|
Return Value:
|
|
|
|
TRUE - successfully got the access mask.
|
|
FALSE otherwise.
|
|
|
|
DevNote:
|
|
|
|
UNDONE - This might not be a complete list...can add as we debug more apps.
|
|
|
|
History:
|
|
|
|
02/12/2001 maonis Created
|
|
|
|
--*/
|
|
|
|
BOOL
|
|
RequestWriteAccess(
|
|
IN DWORD dwCreationDisposition,
|
|
IN DWORD dwDesiredAccess
|
|
)
|
|
{
|
|
MapGenericMask(&dwDesiredAccess, &s_gmFile);
|
|
|
|
if ((dwCreationDisposition != OPEN_EXISTING) ||
|
|
(dwDesiredAccess & DELETE) ||
|
|
// Generally, app would not specify FILE_WRITE_DATA directly, and if
|
|
// it specifies GENERIC_WRITE, it will get mapped to FILE_WRITE_DATA
|
|
// OR other things so checking FILE_WRITE_DATA is sufficient.
|
|
(dwDesiredAccess & FILE_WRITE_DATA))
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/*++
|
|
|
|
Function Description:
|
|
|
|
Add or remove the SE_PRIVILEGE_ENABLED from the current process.
|
|
|
|
|
|
Arguments:
|
|
|
|
IN pwszPrivilege Name of the priv. to modify.
|
|
IN fEnable Add or remove SE_PRIVILEGE_ENABLED
|
|
|
|
Return Value:
|
|
|
|
TRUE - if SE_PRIVILEGE_ENABLED was successfully added or removed.
|
|
FALSE otherwise.
|
|
|
|
04/03/2001 maonis Created
|
|
|
|
--*/
|
|
|
|
BOOL
|
|
AdjustPrivilege(
|
|
LPCWSTR pwszPrivilege,
|
|
BOOL fEnable
|
|
)
|
|
{
|
|
HANDLE hToken;
|
|
TOKEN_PRIVILEGES tp;
|
|
BOOL fRes = FALSE;
|
|
|
|
// Obtain the process token.
|
|
if (OpenProcessToken(
|
|
GetCurrentProcess(),
|
|
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
|
|
&hToken))
|
|
{
|
|
// Get the LUID.
|
|
if (LookupPrivilegeValueW(NULL, pwszPrivilege, &tp.Privileges[0].Luid))
|
|
{
|
|
tp.PrivilegeCount = 1;
|
|
|
|
tp.Privileges[0].Attributes = (fEnable ? SE_PRIVILEGE_ENABLED : 0);
|
|
|
|
// Enable or disable the privilege.
|
|
if (AdjustTokenPrivileges(
|
|
hToken,
|
|
FALSE,
|
|
&tp,
|
|
0,
|
|
(PTOKEN_PRIVILEGES)NULL,
|
|
0))
|
|
{
|
|
fRes = TRUE;
|
|
}
|
|
}
|
|
|
|
CloseHandle(hToken);
|
|
}
|
|
|
|
return fRes;
|
|
}
|
|
|
|
|
|
|
|
}; // end of namespace ShimLib
|