//+--------------------------------------------------------------------------- // // 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 #pragma hdrstop #include #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 //+--------------------------------------------------------------------------- // // Function: FCheckGroupMembership // // Purpose: Returns TRUE if the logged on user is a member of the // specified group. // // Arguments: // dwRID [in] Group RID to check against. // // Returns: TRUE if the logged on user is a member of the specified group // // Author: scottbri 14 Sept 1998 // // Notes: // BOOL FCheckGroupMembership(IN 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 ( OUT 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 ( OUT 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(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 ( IN 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(IN DWORD dw, IN DWORD dwVal) { DWORD dwBit = (1 << dw); g_dwPermMask = (g_dwPermMask & ~dwBit) | ((0==dwVal) ? 0 : dwBit); } inline BOOL NCPERM_CHECKBIT(IN 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(IN DWORD dwUserType) { return (dwUserType & USER_TYPE_ADMIN); } inline BOOL NCPERM_USER_IS_NETCONFIGOPS(IN DWORD dwUserType) { return (dwUserType & USER_TYPE_NETCONFIGOPS); } inline BOOL NCPERM_USER_IS_POWERUSER(IN DWORD dwUserType) { return (dwUserType & USER_TYPE_POWERUSER); } inline BOOL NCPERM_USER_IS_USER(IN DWORD dwUserType) { return (dwUserType & USER_TYPE_USER); } inline BOOL NCPERM_USER_IS_GUEST(IN DWORD dwUserType) { return (dwUserType & USER_TYPE_GUEST); } inline BOOL NCPERM_APPLIES_TO_CURRENT_USER(IN DWORD dwUserType, IN DWORD dwApplyMask) { return (dwUserType & dwApplyMask); } inline int NCPERM_FIND_MAP_ENTRY(IN 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(IN 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(IN ULONG ulPerm, IN 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. // ISSUE: Revisit frequently. This may change. 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_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 (E.g. NCPERM_xxxx) // pGPBase [in] CGroupPolicyBase - the netman Group Policy Engine. In // order to check a location aware policy, this must be // passed in. // // Returns: BOOL, TRUE if the requested permission is granted to the user // BOOL FHasPermission(IN ULONG ulPerm, IN CGroupPolicyBase* pGPBase) { TraceFileFunc(ttidDefault); DWORD dwCurrentUserType; Assert(static_cast(ulPerm) >= NCPERM_Min); Assert(static_cast(ulPerm) <= NCPERM_Max); g_pNetmanGPNLA = pGPBase; //if we are using DataCenter, Back Office, //Small Business Center, or Blade, then don't 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_DATACENTER | VER_SUITE_BACKOFFICE | VER_SUITE_SMALLBUSINESS_RESTRICTED | VER_SUITE_SMALLBUSINESS | VER_SUITE_BLADE; VER_SET_CONDITION(ConditionMask, VER_SUITENAME, VER_OR); 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"); RefreshAllPermission(); g_fPermsInited = TRUE; } 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(ulPerm) >= NCPERM_Min); Assert(static_cast(ulPerm) <= NCPERM_Max); if (!g_fPermsInited) { RefreshAllPermission(); g_fPermsInited = TRUE; } return NCPERM_CHECKBIT(ulPerm); } //+--------------------------------------------------------------------------- // // Function: FProhibitFromAdmins // // Purpose: See if group policies should apply to the administrator // // Arguments: // // Returns: TRUE if it should apply, otherwise false // // Author: ckotze 11 Aug 2000 // // 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); if (SUCCEEDED(hr)) { bEnabled = (dw) ? TRUE : FALSE; } RegCloseKey(hKey); } TraceErrorOptional("FProhibitFromAdmins", hr, (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)); return bEnabled; } //+--------------------------------------------------------------------------- // // Function: RefreshAllPermission // // Purpose: Initializes all permission to the settings from the registry, // and the ACL list below. Stores these to be used by // FHasPermissionFromCache // // Arguments: // none // // Returns: None // 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(&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: ulPerm [in] Group policy number from the USER_PERM_MAP // // // Returns: BOOL. // // Author: ckotze 12 Jun 2000 // // Notes: // BOOL FIsPolicyConfigured(IN 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(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(); }