1388 lines
37 KiB
C++
1388 lines
37 KiB
C++
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1997-2001.
|
|
//
|
|
// File: N C P E R M S . C P P
|
|
//
|
|
// Contents: Common routines for dealing with permissions.
|
|
//
|
|
// Notes: Pollute this under penalty of death.
|
|
//
|
|
// Author: shaunco 20 Sep 1997
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include <pch.h>
|
|
#pragma hdrstop
|
|
#include <ntseapi.h>
|
|
#include "ncbase.h"
|
|
#include "ncdebug.h"
|
|
#include "ncperms.h"
|
|
#include "netconp.h"
|
|
#include "ncreg.h"
|
|
#include "lm.h"
|
|
|
|
CGroupPolicyBase* g_pNetmanGPNLA = NULL;
|
|
|
|
#define INITGUID
|
|
#include <nmclsid.h>
|
|
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: FCheckGroupMembership
|
|
//
|
|
// Purpose: Returns TRUE if the logged on user is a member of the
|
|
// specified group.
|
|
//
|
|
// Arguments:
|
|
// dwRID -
|
|
//
|
|
// Returns: TRUE if the logged on user is a member of the specified group
|
|
//
|
|
// Author: scottbri 14 Sept 1998
|
|
//
|
|
// Notes:
|
|
//
|
|
BOOL FCheckGroupMembership(DWORD dwRID)
|
|
{
|
|
SID_IDENTIFIER_AUTHORITY SidAuth = SECURITY_NT_AUTHORITY;
|
|
PSID psid;
|
|
BOOL fIsMember = FALSE;
|
|
|
|
// Allocate a SID for the Administrators group and check to see
|
|
// if the user is a member.
|
|
//
|
|
if (AllocateAndInitializeSid (&SidAuth, 2,
|
|
SECURITY_BUILTIN_DOMAIN_RID,
|
|
dwRID,
|
|
0, 0, 0, 0, 0, 0,
|
|
&psid))
|
|
{
|
|
if (!CheckTokenMembership (NULL, psid, &fIsMember))
|
|
{
|
|
fIsMember = FALSE;
|
|
TraceLastWin32Error ("FCheckGroupMembership - CheckTokenMemberShip failed.");
|
|
}
|
|
|
|
FreeSid (psid);
|
|
}
|
|
else
|
|
{
|
|
TraceLastWin32Error ("FCheckGroupMembership - AllocateAndInitializeSid failed.");
|
|
}
|
|
|
|
return fIsMember;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: FIsUserAdmin
|
|
//
|
|
// Purpose: Returns TRUE if the logged on user is a member of the
|
|
// Administrators local group.
|
|
//
|
|
// Arguments:
|
|
// (none)
|
|
//
|
|
// Returns: TRUE if the logged on user is a member of the
|
|
// Administrators local group. False otherwise.
|
|
//
|
|
// Author: shaunco 19 Mar 1998
|
|
//
|
|
// Notes:
|
|
//
|
|
BOOL
|
|
FIsUserAdmin()
|
|
{
|
|
BOOL fIsMember;
|
|
|
|
// Check the administrators group
|
|
//
|
|
fIsMember = FCheckGroupMembership(DOMAIN_ALIAS_RID_ADMINS);
|
|
|
|
return fIsMember;
|
|
}
|
|
|
|
//#define ALIGN_DWORD(_size) (((_size) + 3) & ~3)
|
|
//#define ALIGN_QWORD(_size) (((_size) + 7) & ~7)
|
|
#define SIZE_ALIGNED_FOR_TYPE(_size, _type) \
|
|
(((_size) + sizeof(_type)-1) & ~(sizeof(_type)-1))
|
|
|
|
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrAllocateSecurityDescriptorAllowAccessToWorld
|
|
//
|
|
// Purpose: Allocate a security descriptor and initialize it to
|
|
// allow access to everyone.
|
|
//
|
|
// Arguments:
|
|
// ppSd [out] Returned security descriptor.
|
|
//
|
|
// Returns: S_OK or an error code.
|
|
//
|
|
// Author: shaunco 10 Nov 1998
|
|
//
|
|
// Notes: Free *ppSd with MemFree.
|
|
//
|
|
HRESULT
|
|
HrAllocateSecurityDescriptorAllowAccessToWorld (
|
|
PSECURITY_DESCRIPTOR* ppSd)
|
|
{
|
|
PSECURITY_DESCRIPTOR pSd = NULL;
|
|
PSID pSid = NULL;
|
|
PACL pDacl = NULL;
|
|
DWORD dwErr = NOERROR;
|
|
DWORD dwAlignSdSize;
|
|
DWORD dwAlignDaclSize;
|
|
DWORD dwSidSize;
|
|
PVOID pvBuffer = NULL;
|
|
|
|
// Here is the buffer we are building.
|
|
//
|
|
// |<- a ->|<- b ->|<- c ->|
|
|
// +-------+--------+------+
|
|
// | p| p| |
|
|
// | SD a| DACL a| SID |
|
|
// | d| d| |
|
|
// +-------+-------+-------+
|
|
// ^ ^ ^
|
|
// | | |
|
|
// | | +--pSid
|
|
// | |
|
|
// | +--pDacl
|
|
// |
|
|
// +--pSd (this is returned via *ppSd)
|
|
//
|
|
// pad is so that pDacl and pSid are aligned properly.
|
|
//
|
|
// a = dwAlignSdSize
|
|
// b = dwAlignDaclSize
|
|
// c = dwSidSize
|
|
//
|
|
|
|
// Initialize output parameter.
|
|
//
|
|
*ppSd = NULL;
|
|
|
|
// Compute the size of the SID. The SID is the well-known SID for World
|
|
// (S-1-1-0).
|
|
//
|
|
dwSidSize = GetSidLengthRequired(1);
|
|
|
|
// Compute the size of the DACL. It has an inherent copy of SID within
|
|
// it so add enough room for it. It also must sized properly so that
|
|
// a pointer to a SID structure can come after it. Hence, we use
|
|
// SIZE_ALIGNED_FOR_TYPE.
|
|
//
|
|
dwAlignDaclSize = SIZE_ALIGNED_FOR_TYPE(
|
|
sizeof(ACCESS_ALLOWED_ACE) + sizeof(ACL) + dwSidSize,
|
|
PSID);
|
|
|
|
// Compute the size of the SD. It must be sized propertly so that a
|
|
// pointer to a DACL structure can come after it. Hence, we use
|
|
// SIZE_ALIGNED_FOR_TYPE.
|
|
//
|
|
dwAlignSdSize = SIZE_ALIGNED_FOR_TYPE(
|
|
sizeof(SECURITY_DESCRIPTOR),
|
|
PACL);
|
|
|
|
// Allocate the buffer big enough for all.
|
|
//
|
|
dwErr = ERROR_OUTOFMEMORY;
|
|
pvBuffer = MemAlloc(dwSidSize + dwAlignDaclSize + dwAlignSdSize);
|
|
if (pvBuffer)
|
|
{
|
|
SID_IDENTIFIER_AUTHORITY SidIdentifierWorldAuth
|
|
= SECURITY_WORLD_SID_AUTHORITY;
|
|
PULONG pSubAuthority;
|
|
|
|
dwErr = NOERROR;
|
|
|
|
// Setup the pointers into the buffer.
|
|
//
|
|
pSd = pvBuffer;
|
|
pDacl = (PACL)((PBYTE)pvBuffer + dwAlignSdSize);
|
|
pSid = (PSID)((PBYTE)pDacl + dwAlignDaclSize);
|
|
|
|
// Initialize pSid as S-1-1-0.
|
|
//
|
|
if (!InitializeSid(
|
|
pSid,
|
|
&SidIdentifierWorldAuth,
|
|
1)) // 1 sub-authority
|
|
{
|
|
dwErr = GetLastError();
|
|
goto finish;
|
|
}
|
|
|
|
pSubAuthority = GetSidSubAuthority(pSid, 0);
|
|
*pSubAuthority = SECURITY_WORLD_RID;
|
|
|
|
// Initialize pDacl.
|
|
//
|
|
if (!InitializeAcl(
|
|
pDacl,
|
|
dwAlignDaclSize,
|
|
ACL_REVISION))
|
|
{
|
|
dwErr = GetLastError();
|
|
goto finish;
|
|
}
|
|
|
|
// Add an access-allowed ACE for S-1-1-0 to pDacl.
|
|
//
|
|
if (!AddAccessAllowedAce(
|
|
pDacl,
|
|
ACL_REVISION,
|
|
STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL,
|
|
pSid))
|
|
{
|
|
dwErr = GetLastError();
|
|
goto finish;
|
|
}
|
|
|
|
// Initialize pSd.
|
|
//
|
|
if (!InitializeSecurityDescriptor(
|
|
pSd,
|
|
SECURITY_DESCRIPTOR_REVISION))
|
|
{
|
|
dwErr = GetLastError();
|
|
goto finish;
|
|
}
|
|
|
|
// Set pSd to use pDacl.
|
|
//
|
|
if (!SetSecurityDescriptorDacl(
|
|
pSd,
|
|
TRUE,
|
|
pDacl,
|
|
FALSE))
|
|
{
|
|
dwErr = GetLastError();
|
|
goto finish;
|
|
}
|
|
|
|
// Set the owner for pSd.
|
|
//
|
|
if (!SetSecurityDescriptorOwner(
|
|
pSd,
|
|
NULL,
|
|
FALSE))
|
|
{
|
|
dwErr = GetLastError();
|
|
goto finish;
|
|
}
|
|
|
|
// Set the group for pSd.
|
|
//
|
|
if (!SetSecurityDescriptorGroup(
|
|
pSd,
|
|
NULL,
|
|
FALSE))
|
|
{
|
|
dwErr = GetLastError();
|
|
goto finish;
|
|
}
|
|
|
|
finish:
|
|
if (!dwErr)
|
|
{
|
|
*ppSd = pSd;
|
|
}
|
|
else
|
|
{
|
|
MemFree(pvBuffer);
|
|
}
|
|
}
|
|
|
|
return HRESULT_FROM_WIN32(dwErr);
|
|
}
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Function: HrEnablePrivilege
|
|
//
|
|
// Purpose: Enables the specified privilege for the current process
|
|
//
|
|
// Arguments:
|
|
// pszPrivilegeName [in] The name of the privilege
|
|
//
|
|
// Returns: HRESULT. S_OK if successful,
|
|
// a converted Win32 error code otherwise
|
|
//
|
|
// Author: billbe 13 Dec 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT
|
|
HrEnablePrivilege (
|
|
IN PCWSTR pszPrivilegeName)
|
|
{
|
|
HANDLE hToken;
|
|
|
|
// Open the thread token in case it is impersonating
|
|
BOOL fWin32Success = OpenThreadToken (GetCurrentThread(),
|
|
TOKEN_ADJUST_PRIVILEGES, TRUE, &hToken);
|
|
|
|
// If there was no token for the thread, open the process token
|
|
//
|
|
if (!fWin32Success && (ERROR_NO_TOKEN == GetLastError ()))
|
|
{
|
|
// Get token to adjust privileges for this process
|
|
fWin32Success = OpenProcessToken (GetCurrentProcess(),
|
|
TOKEN_ADJUST_PRIVILEGES, &hToken);
|
|
}
|
|
|
|
|
|
if (fWin32Success)
|
|
{
|
|
// get the luid that represents the privilege name
|
|
LUID luid;
|
|
fWin32Success = LookupPrivilegeValue(NULL, pszPrivilegeName, &luid);
|
|
|
|
if (fWin32Success)
|
|
{
|
|
// set up the privilege structure
|
|
TOKEN_PRIVILEGES tpNewPrivileges;
|
|
tpNewPrivileges.PrivilegeCount = 1;
|
|
tpNewPrivileges.Privileges[0].Luid = luid;
|
|
tpNewPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
|
|
|
// turn on the privilege
|
|
AdjustTokenPrivileges (hToken, FALSE, &tpNewPrivileges, 0,
|
|
NULL, NULL);
|
|
|
|
if (ERROR_SUCCESS != GetLastError())
|
|
{
|
|
fWin32Success = FALSE;
|
|
}
|
|
}
|
|
|
|
CloseHandle(hToken);
|
|
}
|
|
|
|
HRESULT hr;
|
|
// Convert any errors to an HRESULT
|
|
if (!fWin32Success)
|
|
{
|
|
hr = HrFromLastWin32Error();
|
|
}
|
|
else
|
|
{
|
|
hr = S_OK;
|
|
}
|
|
|
|
TraceError ("HrEnablePrivilege", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrEnableAllPrivileges
|
|
//
|
|
// Purpose: Enables all privileges for the current process.
|
|
//
|
|
// Arguments:
|
|
// pptpOld [out] Returns the previous state of privileges so that they can
|
|
// be restored.
|
|
//
|
|
// Returns: S_OK if successful, Win32 Error otherwise
|
|
//
|
|
// Author: danielwe 11 Aug 1997
|
|
//
|
|
// Notes: The pptpOld parameter should be freed with delete [].
|
|
//
|
|
HRESULT
|
|
HrEnableAllPrivileges (
|
|
TOKEN_PRIVILEGES** pptpOld)
|
|
{
|
|
Assert(pptpOld);
|
|
|
|
HRESULT hr = S_OK;
|
|
HANDLE hTok;
|
|
ULONG cbTok = 4096;
|
|
BOOL fres;
|
|
|
|
// Try opening the thread token first in case of impersonation
|
|
fres = OpenThreadToken(GetCurrentThread(),
|
|
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, TRUE, &hTok);
|
|
|
|
if (!fres && (ERROR_NO_TOKEN == GetLastError()))
|
|
{
|
|
// If there was no thread token open the process token
|
|
fres = OpenProcessToken(GetCurrentProcess(),
|
|
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
|
|
&hTok);
|
|
}
|
|
|
|
if (fres)
|
|
{
|
|
PTOKEN_PRIVILEGES ptpNew;
|
|
hr = E_OUTOFMEMORY;
|
|
ptpNew = (PTOKEN_PRIVILEGES)MemAlloc(cbTok);
|
|
if (ptpNew)
|
|
{
|
|
hr = S_OK;
|
|
|
|
fres = GetTokenInformation(hTok, TokenPrivileges,
|
|
ptpNew, cbTok, &cbTok);
|
|
if (fres)
|
|
{
|
|
//
|
|
// Set the state settings so that all privileges are enabled...
|
|
//
|
|
|
|
if (ptpNew->PrivilegeCount > 0)
|
|
{
|
|
for (ULONG iPriv = 0; iPriv < ptpNew->PrivilegeCount; iPriv++)
|
|
{
|
|
ptpNew->Privileges[iPriv].Attributes = SE_PRIVILEGE_ENABLED;
|
|
}
|
|
}
|
|
|
|
*pptpOld = reinterpret_cast<PTOKEN_PRIVILEGES>(new BYTE[cbTok]);
|
|
|
|
fres = AdjustTokenPrivileges(hTok, FALSE, ptpNew, cbTok, *pptpOld,
|
|
&cbTok);
|
|
}
|
|
|
|
MemFree(ptpNew);
|
|
}
|
|
|
|
CloseHandle(hTok);
|
|
}
|
|
|
|
if (!fres)
|
|
{
|
|
hr = HrFromLastWin32Error();
|
|
}
|
|
|
|
TraceError("HrEnableAllPrivileges", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrRestorePrivileges
|
|
//
|
|
// Purpose: Restores the privileges for the current process after they have
|
|
// have been modified by HrEnableAllPrivileges().
|
|
//
|
|
// Arguments:
|
|
// ptpRestore [in] Previous state of privileges as returned by
|
|
// HrEnableAllPrivileges().
|
|
//
|
|
// Returns: S_OK if successful, Win32 Error otherwise
|
|
//
|
|
// Author: danielwe 11 Aug 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT
|
|
HrRestorePrivileges (
|
|
TOKEN_PRIVILEGES* ptpRestore)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
HANDLE hTok = NULL ;
|
|
BOOL fres = FALSE;
|
|
|
|
Assert(ptpRestore);
|
|
|
|
if (OpenProcessToken(GetCurrentProcess(),
|
|
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
|
|
&hTok))
|
|
{
|
|
if (AdjustTokenPrivileges(hTok, FALSE, ptpRestore, 0, NULL, NULL))
|
|
{
|
|
fres = TRUE;
|
|
}
|
|
|
|
CloseHandle(hTok);
|
|
}
|
|
|
|
if (!fres)
|
|
{
|
|
hr = HrFromLastWin32Error();
|
|
}
|
|
|
|
TraceError("HrRestorePrivileges", hr);
|
|
return hr;
|
|
}
|
|
|
|
extern const DECLSPEC_SELECTANY WCHAR c_szConnectionsPolicies[] =
|
|
L"Software\\Policies\\Microsoft\\Windows\\Network Connections";
|
|
|
|
// User types
|
|
const DWORD USER_TYPE_ADMIN = 0x00000001;
|
|
const DWORD USER_TYPE_NETCONFIGOPS = 0x00000002;
|
|
const DWORD USER_TYPE_POWERUSER = 0x00000004;
|
|
const DWORD USER_TYPE_USER = 0x00000008;
|
|
const DWORD USER_TYPE_GUEST = 0x00000010;
|
|
|
|
typedef struct
|
|
{
|
|
DWORD dwShift;
|
|
PCWSTR pszValue;
|
|
DWORD dwApplyMask;
|
|
} PERM_MAP_STRUCT;
|
|
|
|
extern const DECLSPEC_SELECTANY PERM_MAP_STRUCT USER_PERM_MAP[] =
|
|
{
|
|
{NCPERM_NewConnectionWizard, L"NC_NewConnectionWizard", APPLY_TO_ALL_USERS},
|
|
{NCPERM_Statistics, L"NC_Statistics", APPLY_TO_ALL_USERS},
|
|
{NCPERM_AddRemoveComponents, L"NC_AddRemoveComponents", APPLY_TO_ADMIN},
|
|
{NCPERM_RasConnect, L"NC_RasConnect", APPLY_TO_ALL_USERS},
|
|
{NCPERM_LanConnect, L"NC_LanConnect", APPLY_TO_ALL_USERS},
|
|
{NCPERM_DeleteConnection, L"NC_DeleteConnection", APPLY_TO_ALL_USERS},
|
|
{NCPERM_DeleteAllUserConnection, L"NC_DeleteAllUserConnection", APPLY_TO_ALL_USERS},
|
|
{NCPERM_RenameConnection, L"NC_RenameConnection", APPLY_TO_ALL_USERS},
|
|
{NCPERM_RenameMyRasConnection, L"NC_RenameMyRasConnection", APPLY_TO_ALL_USERS},
|
|
{NCPERM_ChangeBindState, L"NC_ChangeBindState", APPLY_TO_ADMIN},
|
|
{NCPERM_AdvancedSettings, L"NC_AdvancedSettings", APPLY_TO_ADMIN},
|
|
{NCPERM_DialupPrefs, L"NC_DialupPrefs", APPLY_TO_ALL_USERS},
|
|
{NCPERM_LanChangeProperties, L"NC_LanChangeProperties", APPLY_TO_OPS_OR_ADMIN},
|
|
{NCPERM_RasChangeProperties, L"NC_RasChangeProperties", APPLY_TO_ALL_USERS},
|
|
{NCPERM_LanProperties, L"NC_LanProperties", APPLY_TO_ALL_USERS},
|
|
{NCPERM_RasMyProperties, L"NC_RasMyProperties", APPLY_TO_ALL_USERS},
|
|
{NCPERM_RasAllUserProperties, L"NC_RasAllUserProperties", APPLY_TO_ALL_USERS},
|
|
{NCPERM_ShowSharedAccessUi, L"NC_ShowSharedAccessUi", APPLY_TO_LOCATION},
|
|
{NCPERM_AllowAdvancedTCPIPConfig, L"NC_AllowAdvancedTCPIPConfig", APPLY_TO_ALL_USERS},
|
|
{NCPERM_PersonalFirewallConfig, L"NC_PersonalFirewallConfig", APPLY_TO_LOCATION},
|
|
{NCPERM_AllowNetBridge_NLA, L"NC_AllowNetBridge_NLA", APPLY_TO_LOCATION},
|
|
{NCPERM_ICSClientApp, L"NC_ICSClientApp", APPLY_TO_LOCATION},
|
|
{NCPERM_EnDisComponentsAllUserRas, L"NC_EnDisComponentsAllUserRas", APPLY_TO_NON_ADMINS},
|
|
{NCPERM_EnDisComponentsMyRas, L"NC_EnDisComponentsMyRas", APPLY_TO_NON_ADMINS},
|
|
{NCPERM_ChangeMyRasProperties, L"NC_ChangeMyRasProperties", APPLY_TO_NON_ADMINS},
|
|
{NCPERM_ChangeAllUserRasProperties, L"NC_ChangeAllUserRasProperties", APPLY_TO_NON_ADMINS},
|
|
{NCPERM_RenameLanConnection, L"NC_RenameLanConnection", APPLY_TO_NON_ADMINS},
|
|
{NCPERM_RenameAllUserRasConnection, L"NC_RenameAllUserRasConnection", APPLY_TO_NON_ADMINS},
|
|
{NCPERM_IpcfgOperation, L"NC_IPConfigOperation", APPLY_TO_ALL_USERS},
|
|
{NCPERM_Repair, L"NC_Repair", APPLY_TO_ALL_USERS},
|
|
};
|
|
|
|
extern const DECLSPEC_SELECTANY PERM_MAP_STRUCT MACHINE_PERM_MAP[] =
|
|
{
|
|
{NCPERM_ShowSharedAccessUi, L"NC_ShowSharedAccessUi", APPLY_TO_LOCATION},
|
|
{NCPERM_PersonalFirewallConfig, L"NC_PersonalFirewallConfig", APPLY_TO_LOCATION},
|
|
{NCPERM_ICSClientApp, L"NC_ICSClientApp", APPLY_TO_LOCATION},
|
|
{NCPERM_AllowNetBridge_NLA, L"NC_AllowNetBridge_NLA", APPLY_TO_LOCATION}
|
|
};
|
|
|
|
extern const LONG NCPERM_Min = NCPERM_NewConnectionWizard;
|
|
extern const LONG NCPERM_Max = NCPERM_Repair;
|
|
|
|
// External policies (for now, only explorer has polices that affect our processing
|
|
//
|
|
extern const WCHAR c_szExplorerPolicies[] =
|
|
L"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer";
|
|
|
|
extern const WCHAR c_szNCPolicyForAdministrators[] =
|
|
L"NC_EnableAdminProhibits";
|
|
|
|
extern const WCHAR c_szNoNetworkConnectionPolicy[] =
|
|
L"NoNetworkConnections";
|
|
|
|
|
|
static DWORD g_dwPermMask;
|
|
static BOOL g_fPermsInited = FALSE;
|
|
|
|
inline
|
|
VOID NCPERM_SETBIT(DWORD dw, DWORD dwVal)
|
|
{
|
|
DWORD dwBit = (1 << dw);
|
|
g_dwPermMask = (g_dwPermMask & ~dwBit) | ((0==dwVal) ? 0 : dwBit);
|
|
}
|
|
|
|
inline
|
|
BOOL NCPERM_CHECKBIT(DWORD dw)
|
|
{
|
|
#ifdef DBG
|
|
if (!FIsPolicyConfigured(dw))
|
|
{
|
|
if (0xFFFFFFFF != g_dwDbgPermissionsFail)
|
|
{
|
|
if (FProhibitFromAdmins() || !FIsUserAdmin())
|
|
{
|
|
if ( (1 << dw) & g_dwDbgPermissionsFail)
|
|
{
|
|
TraceTag(ttidDefault, "Failing permissions check due to g_dwDbgPermissionsFail set");
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif // DBG
|
|
|
|
return !!(g_dwPermMask & (1 << dw));
|
|
}
|
|
|
|
inline
|
|
BOOL NCPERM_USER_IS_ADMIN(DWORD dwUserType)
|
|
{
|
|
return (dwUserType & USER_TYPE_ADMIN);
|
|
}
|
|
|
|
inline
|
|
BOOL NCPERM_USER_IS_NETCONFIGOPS(DWORD dwUserType)
|
|
{
|
|
return (dwUserType & USER_TYPE_NETCONFIGOPS);
|
|
}
|
|
|
|
inline
|
|
BOOL NCPERM_USER_IS_POWERUSER(DWORD dwUserType)
|
|
{
|
|
return (dwUserType & USER_TYPE_POWERUSER);
|
|
}
|
|
|
|
inline
|
|
BOOL NCPERM_USER_IS_USER(DWORD dwUserType)
|
|
{
|
|
return (dwUserType & USER_TYPE_USER);
|
|
}
|
|
|
|
inline
|
|
BOOL NCPERM_USER_IS_GUEST(DWORD dwUserType)
|
|
{
|
|
return (dwUserType & USER_TYPE_GUEST);
|
|
}
|
|
|
|
inline
|
|
BOOL NCPERM_APPLIES_TO_CURRENT_USER(DWORD dwUserType, DWORD dwApplyMask)
|
|
{
|
|
return (dwUserType & dwApplyMask);
|
|
}
|
|
|
|
inline
|
|
int NCPERM_FIND_MAP_ENTRY(ULONG ulPerm)
|
|
{
|
|
|
|
for (int i = 0; i < celems(USER_PERM_MAP); i++)
|
|
|
|
{
|
|
if (USER_PERM_MAP[i].dwShift == ulPerm)
|
|
{
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
inline
|
|
BOOL NCPERM_APPLIES_TO_LOCATION(ULONG ulPerm)
|
|
{
|
|
BOOL bAppliesToLocation = FALSE;
|
|
|
|
int nIdx = NCPERM_FIND_MAP_ENTRY(ulPerm);
|
|
|
|
if (nIdx != -1)
|
|
{
|
|
bAppliesToLocation = (USER_PERM_MAP[nIdx].dwApplyMask & APPLY_TO_LOCATION);
|
|
}
|
|
else
|
|
{
|
|
bAppliesToLocation = FALSE;
|
|
}
|
|
return bAppliesToLocation;
|
|
}
|
|
|
|
|
|
inline
|
|
BOOL NCPERM_APPLY_BASED_ON_LOCATION(ULONG ulPerm, DWORD dwPermission)
|
|
{
|
|
DWORD fSameNetwork = FALSE;
|
|
|
|
if (g_pNetmanGPNLA)
|
|
{
|
|
fSameNetwork = g_pNetmanGPNLA->IsSameNetworkAsGroupPolicies();
|
|
}
|
|
|
|
if (!fSameNetwork && NCPERM_APPLIES_TO_LOCATION(ulPerm))
|
|
{
|
|
dwPermission = TRUE;
|
|
}
|
|
return dwPermission;
|
|
}
|
|
|
|
inline
|
|
DWORD NCPERM_USER_TYPE()
|
|
{
|
|
if (FIsUserAdmin())
|
|
{
|
|
return USER_TYPE_ADMIN;
|
|
}
|
|
else if (FIsUserNetworkConfigOps())
|
|
{
|
|
return USER_TYPE_NETCONFIGOPS;
|
|
}
|
|
else if (FIsUserPowerUser())
|
|
{
|
|
return USER_TYPE_POWERUSER;
|
|
}
|
|
else if (FIsUserGuest())
|
|
{
|
|
return USER_TYPE_GUEST;
|
|
}
|
|
|
|
return USER_TYPE_USER;
|
|
}
|
|
|
|
inline
|
|
BOOL IsOsLikePersonal()
|
|
{
|
|
OSVERSIONINFOEXW verInfo = {0};
|
|
ULONGLONG ConditionMask = 0;
|
|
static BOOL fChecked = FALSE;
|
|
static BOOL fOsLikePersonal = FALSE;
|
|
|
|
// Optimization, since OS can't change on the fly. Even a domain join requires a reboot.
|
|
// If that ever changes then this logic needs to be revisited.
|
|
|
|
if (fChecked)
|
|
{
|
|
return fOsLikePersonal;
|
|
}
|
|
|
|
verInfo.dwOSVersionInfoSize = sizeof(verInfo);
|
|
verInfo.wProductType = VER_NT_WORKSTATION;
|
|
|
|
VER_SET_CONDITION(ConditionMask, VER_PRODUCT_TYPE, VER_LESS_EQUAL);
|
|
|
|
if(VerifyVersionInfo(&verInfo, VER_PRODUCT_TYPE, ConditionMask))
|
|
{
|
|
LPWSTR pszDomain;
|
|
NETSETUP_JOIN_STATUS njs = NetSetupUnknownStatus;
|
|
if (NERR_Success == NetGetJoinInformation(NULL, &pszDomain, &njs))
|
|
{
|
|
NetApiBufferFree(pszDomain);
|
|
}
|
|
|
|
if (NetSetupDomainName == njs)
|
|
{
|
|
fOsLikePersonal = FALSE; // connected to domain
|
|
}
|
|
else
|
|
{
|
|
fOsLikePersonal = TRUE; // Professional, but not a domain member
|
|
}
|
|
}
|
|
else
|
|
{
|
|
fOsLikePersonal = FALSE;
|
|
}
|
|
|
|
fChecked = TRUE;
|
|
|
|
return fOsLikePersonal;
|
|
}
|
|
|
|
|
|
const ULONG c_arrayHomenetPerms[] =
|
|
{
|
|
NCPERM_PersonalFirewallConfig,
|
|
NCPERM_AllowNetBridge_NLA,
|
|
NCPERM_ICSClientApp,
|
|
NCPERM_ShowSharedAccessUi
|
|
};
|
|
|
|
#ifdef DBG
|
|
ULONG g_dwDbgPermissionsFail = 0xFFFFFFFF;
|
|
ULONG g_dwDbgWin2kPoliciesSet = 0xFFFFFFFF;
|
|
#endif // DBG
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: FHasPermission
|
|
//
|
|
// Purpose: Called to determine if the requested permissions are available
|
|
//
|
|
// Arguments:
|
|
// ulPerm [in] permission flags
|
|
//
|
|
// Returns: BOOL, TRUE if the requested permission is granted to the user
|
|
//
|
|
BOOL
|
|
FHasPermission(ULONG ulPerm, CGroupPolicyBase* pGPBase)
|
|
{
|
|
TraceFileFunc(ttidDefault);
|
|
|
|
DWORD dwCurrentUserType;
|
|
|
|
Assert(static_cast<LONG>(ulPerm) >= NCPERM_Min);
|
|
Assert(static_cast<LONG>(ulPerm) <= NCPERM_Max);
|
|
|
|
g_pNetmanGPNLA = pGPBase;
|
|
|
|
//if the requested is from a homenet component and we are using DataCenter or
|
|
//Advanced Server, than dont grant the permission
|
|
for (int i = 0; i < celems(c_arrayHomenetPerms); i++)
|
|
{
|
|
if (c_arrayHomenetPerms[i] == ulPerm)
|
|
{
|
|
// On IA64, all homenet technologies are unavailable.
|
|
#ifndef _WIN64
|
|
// Look for the enterprise SKUs
|
|
OSVERSIONINFOEXW verInfo = {0};
|
|
ULONGLONG ConditionMask = 0;
|
|
verInfo.dwOSVersionInfoSize = sizeof(verInfo);
|
|
verInfo.wSuiteMask = VER_SUITE_ENTERPRISE;
|
|
|
|
VER_SET_CONDITION(ConditionMask, VER_SUITENAME, VER_AND);
|
|
|
|
if(VerifyVersionInfo(&verInfo, VER_SUITENAME, ConditionMask))
|
|
#endif
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
dwCurrentUserType = NCPERM_USER_TYPE();
|
|
|
|
if (NCPERM_USER_IS_ADMIN(dwCurrentUserType) && !FProhibitFromAdmins() && !NCPERM_APPLIES_TO_LOCATION(ulPerm))
|
|
{
|
|
// If user is admin and we're not supposed to revoke
|
|
// anything from admins and this is not a location aware policy
|
|
// then just return TRUE
|
|
return TRUE;
|
|
}
|
|
|
|
if (!g_fPermsInited)
|
|
{
|
|
TraceTag(ttidDefault, "Initializing permissions");
|
|
g_fPermsInited = TRUE;
|
|
RefreshAllPermission();
|
|
}
|
|
else
|
|
{
|
|
// update the requested permission only
|
|
HRESULT hr = S_OK;
|
|
HKEY hkey = NULL;
|
|
DWORD dw = 0;
|
|
|
|
switch(ulPerm)
|
|
{
|
|
case NCPERM_OpenConnectionsFolder:
|
|
TraceTag(ttidDefault, "Reading OpenConnectionsFolder permissions");
|
|
hr = HrRegOpenKeyEx(HKEY_CURRENT_USER, c_szExplorerPolicies,
|
|
KEY_READ, &hkey);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
TraceTag(ttidDefault, "Opened explorer policies");
|
|
hr = HrRegQueryDword(hkey, c_szNoNetworkConnectionPolicy, &dw);
|
|
if (SUCCEEDED(hr) && dw)
|
|
{
|
|
TraceTag(ttidDefault,
|
|
"Explorer 'No open connections folder' policy: %d", dw);
|
|
NCPERM_SETBIT(NCPERM_OpenConnectionsFolder, 0);
|
|
|
|
}
|
|
|
|
RegCloseKey(hkey);
|
|
hkey = NULL;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
hr = HrRegOpenKeyEx(HKEY_CURRENT_USER, c_szConnectionsPolicies,
|
|
KEY_READ, &hkey);
|
|
if (S_OK == hr)
|
|
{
|
|
DWORD dw;
|
|
|
|
// Read the User Policy
|
|
for (UINT nIdx=0; nIdx<celems(USER_PERM_MAP); nIdx++)
|
|
{
|
|
if (ulPerm == USER_PERM_MAP[nIdx].dwShift && NCPERM_APPLIES_TO_CURRENT_USER(dwCurrentUserType, USER_PERM_MAP[nIdx].dwApplyMask))
|
|
{
|
|
hr = HrRegQueryDword(hkey, USER_PERM_MAP[nIdx].pszValue, &dw);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
NCPERM_SETBIT(USER_PERM_MAP[nIdx].dwShift, dw);
|
|
}
|
|
}
|
|
}
|
|
|
|
RegCloseKey(hkey);
|
|
}
|
|
|
|
// Read the machine policy
|
|
//
|
|
hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szConnectionsPolicies,
|
|
KEY_READ, &hkey);
|
|
if (S_OK == hr)
|
|
{
|
|
DWORD dw;
|
|
|
|
for (UINT nIdx=0; nIdx<celems(MACHINE_PERM_MAP); nIdx++)
|
|
{
|
|
if (ulPerm == MACHINE_PERM_MAP[nIdx].dwShift)
|
|
{
|
|
hr = HrRegQueryDword(hkey, MACHINE_PERM_MAP[nIdx].pszValue, &dw);
|
|
if (S_OK == hr)
|
|
{
|
|
NCPERM_SETBIT(MACHINE_PERM_MAP[nIdx].dwShift, NCPERM_APPLY_BASED_ON_LOCATION(ulPerm, dw));
|
|
}
|
|
}
|
|
}
|
|
|
|
RegCloseKey(hkey);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
return NCPERM_CHECKBIT(ulPerm);
|
|
}
|
|
|
|
|
|
BOOL
|
|
FHasPermissionFromCache(ULONG ulPerm)
|
|
{
|
|
Assert(static_cast<LONG>(ulPerm) >= NCPERM_Min);
|
|
Assert(static_cast<LONG>(ulPerm) <= NCPERM_Max);
|
|
|
|
if (!g_fPermsInited)
|
|
{
|
|
g_fPermsInited = TRUE;
|
|
RefreshAllPermission();
|
|
}
|
|
|
|
return NCPERM_CHECKBIT(ulPerm);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrRestorePrivileges
|
|
//
|
|
// Purpose: Restores the privileges for the current process after they have
|
|
// have been modified by HrEnableAllPrivileges().
|
|
//
|
|
// Arguments:
|
|
// ptpRestore [in] Previous state of privileges as returned by
|
|
// HrEnableAllPrivileges().
|
|
//
|
|
// Returns: S_OK if successful, Win32 Error otherwise
|
|
//
|
|
// Author: danielwe 11 Aug 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
BOOL FProhibitFromAdmins()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
HKEY hKey;
|
|
DWORD dw;
|
|
BOOL bEnabled = FALSE;
|
|
|
|
#ifdef DBG
|
|
if (0xFFFFFFFF != g_dwDbgWin2kPoliciesSet)
|
|
{
|
|
return g_dwDbgWin2kPoliciesSet;
|
|
}
|
|
#endif // DBG
|
|
|
|
hr = HrRegOpenKeyEx(HKEY_CURRENT_USER, c_szConnectionsPolicies,
|
|
KEY_READ, &hKey);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
hr = HrRegQueryDword(hKey, c_szNCPolicyForAdministrators, &dw);
|
|
bEnabled = (dw) ? TRUE : FALSE;
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
TraceErrorOptional("FProhibitFromAdmins", hr, (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr));
|
|
|
|
return bEnabled;
|
|
}
|
|
|
|
VOID RefreshAllPermission()
|
|
{
|
|
DWORD dwCurrentUserType;
|
|
HKEY hkey;
|
|
HRESULT hr;
|
|
DWORD dw;
|
|
|
|
dwCurrentUserType = NCPERM_USER_TYPE();
|
|
|
|
g_dwPermMask = 0;
|
|
|
|
// If Admin assume all rights
|
|
//
|
|
if (NCPERM_USER_IS_ADMIN(dwCurrentUserType))
|
|
{
|
|
// Cheat a little by setting all bits to one
|
|
//
|
|
g_dwPermMask = 0xFFFFFFFF;
|
|
|
|
// If this policy is not set, then we don't need to worry about reading the regkeys
|
|
// since we can never take anything away from Admins.
|
|
}
|
|
else if (NCPERM_USER_IS_NETCONFIGOPS(dwCurrentUserType))
|
|
{
|
|
NCPERM_SETBIT(NCPERM_NewConnectionWizard, 1);
|
|
NCPERM_SETBIT(NCPERM_Statistics, 1);
|
|
NCPERM_SETBIT(NCPERM_RasConnect, 1);
|
|
NCPERM_SETBIT(NCPERM_DeleteConnection, 1);
|
|
NCPERM_SETBIT(NCPERM_DeleteAllUserConnection, 1);
|
|
NCPERM_SETBIT(NCPERM_RenameConnection, 1);
|
|
NCPERM_SETBIT(NCPERM_RenameMyRasConnection, 1);
|
|
NCPERM_SETBIT(NCPERM_RenameAllUserRasConnection, 1);
|
|
NCPERM_SETBIT(NCPERM_RenameLanConnection, 1);
|
|
NCPERM_SETBIT(NCPERM_DialupPrefs, 1);
|
|
NCPERM_SETBIT(NCPERM_RasChangeProperties, 1);
|
|
NCPERM_SETBIT(NCPERM_RasMyProperties, 1);
|
|
NCPERM_SETBIT(NCPERM_RasAllUserProperties, 1);
|
|
NCPERM_SETBIT(NCPERM_ChangeAllUserRasProperties, 1);
|
|
NCPERM_SETBIT(NCPERM_LanProperties, 1);
|
|
NCPERM_SETBIT(NCPERM_LanChangeProperties, 1);
|
|
NCPERM_SETBIT(NCPERM_AllowAdvancedTCPIPConfig, 1);
|
|
NCPERM_SETBIT(NCPERM_OpenConnectionsFolder, 1);
|
|
NCPERM_SETBIT(NCPERM_LanConnect, 1);
|
|
NCPERM_SETBIT(NCPERM_EnDisComponentsAllUserRas, 1);
|
|
NCPERM_SETBIT(NCPERM_EnDisComponentsMyRas, 1);
|
|
NCPERM_SETBIT(NCPERM_IpcfgOperation, 1);
|
|
NCPERM_SETBIT(NCPERM_Repair, 1);
|
|
}
|
|
else if (NCPERM_USER_IS_POWERUSER(dwCurrentUserType))
|
|
{
|
|
NCPERM_SETBIT(NCPERM_Repair, 1);
|
|
|
|
// Rest should be like NCPERM_USER_IS_USER
|
|
NCPERM_SETBIT(NCPERM_NewConnectionWizard, 1);
|
|
NCPERM_SETBIT(NCPERM_Statistics, 1);
|
|
NCPERM_SETBIT(NCPERM_RasConnect, 1);
|
|
NCPERM_SETBIT(NCPERM_DeleteConnection, 1);
|
|
NCPERM_SETBIT(NCPERM_RenameMyRasConnection, 1);
|
|
NCPERM_SETBIT(NCPERM_DialupPrefs, 1);
|
|
NCPERM_SETBIT(NCPERM_RasChangeProperties, 1);
|
|
NCPERM_SETBIT(NCPERM_RasMyProperties, 1);
|
|
NCPERM_SETBIT(NCPERM_AllowAdvancedTCPIPConfig, 1);
|
|
NCPERM_SETBIT(NCPERM_LanProperties, 1);
|
|
NCPERM_SETBIT(NCPERM_OpenConnectionsFolder, 1);
|
|
if (IsOsLikePersonal())
|
|
{
|
|
NCPERM_SETBIT(NCPERM_RasAllUserProperties, 1);
|
|
NCPERM_SETBIT(NCPERM_ChangeAllUserRasProperties, 1);
|
|
}
|
|
}
|
|
else if (NCPERM_USER_IS_USER(dwCurrentUserType))
|
|
{
|
|
NCPERM_SETBIT(NCPERM_NewConnectionWizard, 1);
|
|
NCPERM_SETBIT(NCPERM_Statistics, 1);
|
|
NCPERM_SETBIT(NCPERM_RasConnect, 1);
|
|
NCPERM_SETBIT(NCPERM_DeleteConnection, 1);
|
|
NCPERM_SETBIT(NCPERM_RenameMyRasConnection, 1);
|
|
NCPERM_SETBIT(NCPERM_DialupPrefs, 1);
|
|
NCPERM_SETBIT(NCPERM_RasChangeProperties, 1);
|
|
NCPERM_SETBIT(NCPERM_RasMyProperties, 1);
|
|
NCPERM_SETBIT(NCPERM_AllowAdvancedTCPIPConfig, 1);
|
|
NCPERM_SETBIT(NCPERM_LanProperties, 1);
|
|
NCPERM_SETBIT(NCPERM_OpenConnectionsFolder, 1);
|
|
if (IsOsLikePersonal())
|
|
{
|
|
NCPERM_SETBIT(NCPERM_RasAllUserProperties, 1);
|
|
NCPERM_SETBIT(NCPERM_ChangeAllUserRasProperties, 1);
|
|
}
|
|
}
|
|
else if (NCPERM_USER_IS_GUEST(dwCurrentUserType))
|
|
{
|
|
NCPERM_SETBIT(NCPERM_Statistics, 1);
|
|
NCPERM_SETBIT(NCPERM_OpenConnectionsFolder, 1);
|
|
}
|
|
|
|
if (FProhibitFromAdmins() || !NCPERM_USER_IS_ADMIN(dwCurrentUserType))
|
|
{
|
|
// Read folder policy
|
|
hr = HrRegOpenKeyEx(HKEY_CURRENT_USER, c_szExplorerPolicies,
|
|
KEY_READ, &hkey);
|
|
if (S_OK == hr)
|
|
{
|
|
TraceTag(ttidDefault, "Opened Explorer Policy reg key");
|
|
|
|
hr = HrRegQueryDword(hkey, c_szNoNetworkConnectionPolicy, &dw);
|
|
if (SUCCEEDED(hr) && dw)
|
|
{
|
|
TraceTag(ttidDefault, "Explorer 'No open connections folder' policy: %d", dw);
|
|
NCPERM_SETBIT(NCPERM_OpenConnectionsFolder, 0);
|
|
}
|
|
|
|
RegCloseKey(hkey);
|
|
|
|
hkey = NULL;
|
|
}
|
|
|
|
// Read the user policy
|
|
//
|
|
hr = HrRegOpenKeyEx(HKEY_CURRENT_USER, c_szConnectionsPolicies,
|
|
KEY_READ, &hkey);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
for (UINT nIdx=0; nIdx<celems(USER_PERM_MAP); nIdx++)
|
|
{
|
|
if (NCPERM_APPLIES_TO_CURRENT_USER(dwCurrentUserType, USER_PERM_MAP[nIdx].dwApplyMask))
|
|
{
|
|
hr = HrRegQueryDword(hkey, USER_PERM_MAP[nIdx].pszValue, &dw);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
NCPERM_SETBIT(USER_PERM_MAP[nIdx].dwShift, dw);
|
|
}
|
|
}
|
|
}
|
|
|
|
RegCloseKey(hkey);
|
|
|
|
}
|
|
}
|
|
|
|
// Read the machine policy
|
|
//
|
|
hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szConnectionsPolicies,
|
|
KEY_READ, &hkey);
|
|
if (S_OK == hr)
|
|
{
|
|
DWORD dw;
|
|
|
|
for (UINT nIdx=0; nIdx<celems(MACHINE_PERM_MAP); nIdx++)
|
|
{
|
|
hr = HrRegQueryDword(hkey, MACHINE_PERM_MAP[nIdx].pszValue, &dw);
|
|
if (S_OK == hr)
|
|
{
|
|
NCPERM_SETBIT(MACHINE_PERM_MAP[nIdx].dwShift, NCPERM_APPLY_BASED_ON_LOCATION(MACHINE_PERM_MAP[nIdx].dwShift, dw));
|
|
}
|
|
}
|
|
|
|
RegCloseKey(hkey);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: IsHNetAllowed
|
|
//
|
|
// Purpose: Verify the permission to use/enable (ICS/Firewall and create bridge network)
|
|
//
|
|
// Checks the following:
|
|
//
|
|
// Does the architecture / SKU permit the use of homenet technologies?
|
|
// Does group policy allow the particular technology?
|
|
// Is the user an Admin and are admins allowed access to this technology?
|
|
//
|
|
// Example scenario. The user is a Admin but ITG disables the right to create bridge this function would return FALSE
|
|
//
|
|
BOOL
|
|
IsHNetAllowed(
|
|
DWORD dwPerm
|
|
)
|
|
{
|
|
#ifndef _WIN64
|
|
BOOL fPermission = false;
|
|
OSVERSIONINFOEXW verInfo = {0};
|
|
ULONGLONG ConditionMask = 0;
|
|
|
|
// Look for the enterprise SKUs
|
|
verInfo.dwOSVersionInfoSize = sizeof(verInfo);
|
|
verInfo.wSuiteMask = VER_SUITE_ENTERPRISE;
|
|
|
|
VER_SET_CONDITION(ConditionMask, VER_SUITENAME, VER_AND);
|
|
|
|
if ( VerifyVersionInfo(&verInfo, VER_SUITENAME, ConditionMask) )
|
|
{
|
|
// Homenet technologies are not available on enterprise SKUs
|
|
return FALSE;
|
|
}
|
|
|
|
if ( FIsUserAdmin() && !FProhibitFromAdmins() )
|
|
{
|
|
HRESULT hr;
|
|
INetMachinePolicies* pMachinePolicy;
|
|
|
|
hr = CoCreateInstance(
|
|
CLSID_NetGroupPolicies,
|
|
NULL,
|
|
CLSCTX_SERVER,
|
|
IID_INetMachinePolicies,
|
|
reinterpret_cast<void **>(&pMachinePolicy)
|
|
);
|
|
|
|
if ( SUCCEEDED(hr) )
|
|
{
|
|
hr = pMachinePolicy->VerifyPermission(dwPerm, &fPermission);
|
|
pMachinePolicy->Release();
|
|
}
|
|
}
|
|
|
|
return fPermission;
|
|
|
|
#else // #ifndef _WIN64
|
|
|
|
// On IA64, homenet technologies are not available at all.
|
|
return FALSE;
|
|
|
|
#endif
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: FIsUserNetworkConfigOps
|
|
//
|
|
// Purpose: Checks to see if the current user is a NetConfig Operator
|
|
//
|
|
//
|
|
// Arguments:
|
|
// none.
|
|
//
|
|
//
|
|
// Returns: BOOL.
|
|
//
|
|
// Author: ckotze 12 Jun 2000
|
|
//
|
|
// Notes:
|
|
//
|
|
BOOL FIsUserNetworkConfigOps()
|
|
{
|
|
BOOL fIsMember;
|
|
|
|
fIsMember = FCheckGroupMembership(DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS);
|
|
|
|
return fIsMember;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: FIsUserPowerUser
|
|
//
|
|
// Purpose: Checks to see if the current user is a Power User
|
|
//
|
|
//
|
|
// Arguments:
|
|
// none.
|
|
//
|
|
//
|
|
// Returns: BOOL.
|
|
//
|
|
// Author: deonb 9 May 2001
|
|
//
|
|
// Notes:
|
|
//
|
|
BOOL FIsUserPowerUser()
|
|
{
|
|
BOOL fIsMember;
|
|
|
|
fIsMember = FCheckGroupMembership(DOMAIN_ALIAS_RID_POWER_USERS);
|
|
|
|
return fIsMember;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: FIsUserGuest
|
|
//
|
|
// Purpose: Checks to see if the current user is a Guest
|
|
//
|
|
//
|
|
// Arguments:
|
|
// none.
|
|
//
|
|
//
|
|
// Returns: BOOL.
|
|
//
|
|
// Author: ckotze 12 Jun 2000
|
|
//
|
|
// Notes:
|
|
//
|
|
BOOL FIsUserGuest()
|
|
{
|
|
BOOL fIsMember;
|
|
|
|
fIsMember = FCheckGroupMembership(DOMAIN_ALIAS_RID_GUESTS);
|
|
|
|
return fIsMember;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: FIsPolicyConfigured
|
|
//
|
|
// Purpose: Checks to see if the specific policy is configured
|
|
//
|
|
//
|
|
// Arguments:
|
|
// none.
|
|
//
|
|
//
|
|
// Returns: BOOL.
|
|
//
|
|
// Author: ckotze 12 Jun 2000
|
|
//
|
|
// Notes:
|
|
//
|
|
BOOL FIsPolicyConfigured(DWORD ulPerm)
|
|
{
|
|
HRESULT hr;
|
|
HKEY hkey;
|
|
BOOL bConfigured = FALSE;
|
|
|
|
hr = HrRegOpenKeyEx(HKEY_CURRENT_USER, c_szConnectionsPolicies, KEY_READ, &hkey);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
DWORD dw;
|
|
|
|
if (ulPerm == USER_PERM_MAP[ulPerm].dwShift)
|
|
{
|
|
DWORD dw;
|
|
|
|
hr = HrRegQueryDword(hkey, USER_PERM_MAP[static_cast<DWORD>(ulPerm)].pszValue, &dw);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
bConfigured = TRUE;
|
|
}
|
|
}
|
|
|
|
RegCloseKey(hkey);
|
|
}
|
|
|
|
return bConfigured;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: IsSameNetworkAsGroupPolicies
|
|
//
|
|
// Purpose: Checks to see if the current network is the same as where the
|
|
// Group Policies were assigned from.
|
|
//
|
|
// Arguments:
|
|
// none.
|
|
//
|
|
//
|
|
// Returns: BOOL
|
|
//
|
|
// Author: ckotze 05 Jan 2001
|
|
//
|
|
// Notes:
|
|
//
|
|
BOOL IsSameNetworkAsGroupPolicies()
|
|
{
|
|
return g_pNetmanGPNLA->IsSameNetworkAsGroupPolicies();
|
|
}
|
|
|