Source code of Windows XP (NT5)
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.

1387 lines
37 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997-2001.
  5. //
  6. // File: N C P E R M S . C P P
  7. //
  8. // Contents: Common routines for dealing with permissions.
  9. //
  10. // Notes: Pollute this under penalty of death.
  11. //
  12. // Author: shaunco 20 Sep 1997
  13. //
  14. //----------------------------------------------------------------------------
  15. #include <pch.h>
  16. #pragma hdrstop
  17. #include <ntseapi.h>
  18. #include "ncbase.h"
  19. #include "ncdebug.h"
  20. #include "ncperms.h"
  21. #include "netconp.h"
  22. #include "ncreg.h"
  23. #include "lm.h"
  24. CGroupPolicyBase* g_pNetmanGPNLA = NULL;
  25. #define INITGUID
  26. #include <nmclsid.h>
  27. //+---------------------------------------------------------------------------
  28. //
  29. // Function: FCheckGroupMembership
  30. //
  31. // Purpose: Returns TRUE if the logged on user is a member of the
  32. // specified group.
  33. //
  34. // Arguments:
  35. // dwRID -
  36. //
  37. // Returns: TRUE if the logged on user is a member of the specified group
  38. //
  39. // Author: scottbri 14 Sept 1998
  40. //
  41. // Notes:
  42. //
  43. BOOL FCheckGroupMembership(DWORD dwRID)
  44. {
  45. SID_IDENTIFIER_AUTHORITY SidAuth = SECURITY_NT_AUTHORITY;
  46. PSID psid;
  47. BOOL fIsMember = FALSE;
  48. // Allocate a SID for the Administrators group and check to see
  49. // if the user is a member.
  50. //
  51. if (AllocateAndInitializeSid (&SidAuth, 2,
  52. SECURITY_BUILTIN_DOMAIN_RID,
  53. dwRID,
  54. 0, 0, 0, 0, 0, 0,
  55. &psid))
  56. {
  57. if (!CheckTokenMembership (NULL, psid, &fIsMember))
  58. {
  59. fIsMember = FALSE;
  60. TraceLastWin32Error ("FCheckGroupMembership - CheckTokenMemberShip failed.");
  61. }
  62. FreeSid (psid);
  63. }
  64. else
  65. {
  66. TraceLastWin32Error ("FCheckGroupMembership - AllocateAndInitializeSid failed.");
  67. }
  68. return fIsMember;
  69. }
  70. //+---------------------------------------------------------------------------
  71. //
  72. // Function: FIsUserAdmin
  73. //
  74. // Purpose: Returns TRUE if the logged on user is a member of the
  75. // Administrators local group.
  76. //
  77. // Arguments:
  78. // (none)
  79. //
  80. // Returns: TRUE if the logged on user is a member of the
  81. // Administrators local group. False otherwise.
  82. //
  83. // Author: shaunco 19 Mar 1998
  84. //
  85. // Notes:
  86. //
  87. BOOL
  88. FIsUserAdmin()
  89. {
  90. BOOL fIsMember;
  91. // Check the administrators group
  92. //
  93. fIsMember = FCheckGroupMembership(DOMAIN_ALIAS_RID_ADMINS);
  94. return fIsMember;
  95. }
  96. //#define ALIGN_DWORD(_size) (((_size) + 3) & ~3)
  97. //#define ALIGN_QWORD(_size) (((_size) + 7) & ~7)
  98. #define SIZE_ALIGNED_FOR_TYPE(_size, _type) \
  99. (((_size) + sizeof(_type)-1) & ~(sizeof(_type)-1))
  100. //+---------------------------------------------------------------------------
  101. //
  102. // Function: HrAllocateSecurityDescriptorAllowAccessToWorld
  103. //
  104. // Purpose: Allocate a security descriptor and initialize it to
  105. // allow access to everyone.
  106. //
  107. // Arguments:
  108. // ppSd [out] Returned security descriptor.
  109. //
  110. // Returns: S_OK or an error code.
  111. //
  112. // Author: shaunco 10 Nov 1998
  113. //
  114. // Notes: Free *ppSd with MemFree.
  115. //
  116. HRESULT
  117. HrAllocateSecurityDescriptorAllowAccessToWorld (
  118. PSECURITY_DESCRIPTOR* ppSd)
  119. {
  120. PSECURITY_DESCRIPTOR pSd = NULL;
  121. PSID pSid = NULL;
  122. PACL pDacl = NULL;
  123. DWORD dwErr = NOERROR;
  124. DWORD dwAlignSdSize;
  125. DWORD dwAlignDaclSize;
  126. DWORD dwSidSize;
  127. PVOID pvBuffer = NULL;
  128. // Here is the buffer we are building.
  129. //
  130. // |<- a ->|<- b ->|<- c ->|
  131. // +-------+--------+------+
  132. // | p| p| |
  133. // | SD a| DACL a| SID |
  134. // | d| d| |
  135. // +-------+-------+-------+
  136. // ^ ^ ^
  137. // | | |
  138. // | | +--pSid
  139. // | |
  140. // | +--pDacl
  141. // |
  142. // +--pSd (this is returned via *ppSd)
  143. //
  144. // pad is so that pDacl and pSid are aligned properly.
  145. //
  146. // a = dwAlignSdSize
  147. // b = dwAlignDaclSize
  148. // c = dwSidSize
  149. //
  150. // Initialize output parameter.
  151. //
  152. *ppSd = NULL;
  153. // Compute the size of the SID. The SID is the well-known SID for World
  154. // (S-1-1-0).
  155. //
  156. dwSidSize = GetSidLengthRequired(1);
  157. // Compute the size of the DACL. It has an inherent copy of SID within
  158. // it so add enough room for it. It also must sized properly so that
  159. // a pointer to a SID structure can come after it. Hence, we use
  160. // SIZE_ALIGNED_FOR_TYPE.
  161. //
  162. dwAlignDaclSize = SIZE_ALIGNED_FOR_TYPE(
  163. sizeof(ACCESS_ALLOWED_ACE) + sizeof(ACL) + dwSidSize,
  164. PSID);
  165. // Compute the size of the SD. It must be sized propertly so that a
  166. // pointer to a DACL structure can come after it. Hence, we use
  167. // SIZE_ALIGNED_FOR_TYPE.
  168. //
  169. dwAlignSdSize = SIZE_ALIGNED_FOR_TYPE(
  170. sizeof(SECURITY_DESCRIPTOR),
  171. PACL);
  172. // Allocate the buffer big enough for all.
  173. //
  174. dwErr = ERROR_OUTOFMEMORY;
  175. pvBuffer = MemAlloc(dwSidSize + dwAlignDaclSize + dwAlignSdSize);
  176. if (pvBuffer)
  177. {
  178. SID_IDENTIFIER_AUTHORITY SidIdentifierWorldAuth
  179. = SECURITY_WORLD_SID_AUTHORITY;
  180. PULONG pSubAuthority;
  181. dwErr = NOERROR;
  182. // Setup the pointers into the buffer.
  183. //
  184. pSd = pvBuffer;
  185. pDacl = (PACL)((PBYTE)pvBuffer + dwAlignSdSize);
  186. pSid = (PSID)((PBYTE)pDacl + dwAlignDaclSize);
  187. // Initialize pSid as S-1-1-0.
  188. //
  189. if (!InitializeSid(
  190. pSid,
  191. &SidIdentifierWorldAuth,
  192. 1)) // 1 sub-authority
  193. {
  194. dwErr = GetLastError();
  195. goto finish;
  196. }
  197. pSubAuthority = GetSidSubAuthority(pSid, 0);
  198. *pSubAuthority = SECURITY_WORLD_RID;
  199. // Initialize pDacl.
  200. //
  201. if (!InitializeAcl(
  202. pDacl,
  203. dwAlignDaclSize,
  204. ACL_REVISION))
  205. {
  206. dwErr = GetLastError();
  207. goto finish;
  208. }
  209. // Add an access-allowed ACE for S-1-1-0 to pDacl.
  210. //
  211. if (!AddAccessAllowedAce(
  212. pDacl,
  213. ACL_REVISION,
  214. STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL,
  215. pSid))
  216. {
  217. dwErr = GetLastError();
  218. goto finish;
  219. }
  220. // Initialize pSd.
  221. //
  222. if (!InitializeSecurityDescriptor(
  223. pSd,
  224. SECURITY_DESCRIPTOR_REVISION))
  225. {
  226. dwErr = GetLastError();
  227. goto finish;
  228. }
  229. // Set pSd to use pDacl.
  230. //
  231. if (!SetSecurityDescriptorDacl(
  232. pSd,
  233. TRUE,
  234. pDacl,
  235. FALSE))
  236. {
  237. dwErr = GetLastError();
  238. goto finish;
  239. }
  240. // Set the owner for pSd.
  241. //
  242. if (!SetSecurityDescriptorOwner(
  243. pSd,
  244. NULL,
  245. FALSE))
  246. {
  247. dwErr = GetLastError();
  248. goto finish;
  249. }
  250. // Set the group for pSd.
  251. //
  252. if (!SetSecurityDescriptorGroup(
  253. pSd,
  254. NULL,
  255. FALSE))
  256. {
  257. dwErr = GetLastError();
  258. goto finish;
  259. }
  260. finish:
  261. if (!dwErr)
  262. {
  263. *ppSd = pSd;
  264. }
  265. else
  266. {
  267. MemFree(pvBuffer);
  268. }
  269. }
  270. return HRESULT_FROM_WIN32(dwErr);
  271. }
  272. //+--------------------------------------------------------------------------
  273. //
  274. // Function: HrEnablePrivilege
  275. //
  276. // Purpose: Enables the specified privilege for the current process
  277. //
  278. // Arguments:
  279. // pszPrivilegeName [in] The name of the privilege
  280. //
  281. // Returns: HRESULT. S_OK if successful,
  282. // a converted Win32 error code otherwise
  283. //
  284. // Author: billbe 13 Dec 1997
  285. //
  286. // Notes:
  287. //
  288. HRESULT
  289. HrEnablePrivilege (
  290. IN PCWSTR pszPrivilegeName)
  291. {
  292. HANDLE hToken;
  293. // Open the thread token in case it is impersonating
  294. BOOL fWin32Success = OpenThreadToken (GetCurrentThread(),
  295. TOKEN_ADJUST_PRIVILEGES, TRUE, &hToken);
  296. // If there was no token for the thread, open the process token
  297. //
  298. if (!fWin32Success && (ERROR_NO_TOKEN == GetLastError ()))
  299. {
  300. // Get token to adjust privileges for this process
  301. fWin32Success = OpenProcessToken (GetCurrentProcess(),
  302. TOKEN_ADJUST_PRIVILEGES, &hToken);
  303. }
  304. if (fWin32Success)
  305. {
  306. // get the luid that represents the privilege name
  307. LUID luid;
  308. fWin32Success = LookupPrivilegeValue(NULL, pszPrivilegeName, &luid);
  309. if (fWin32Success)
  310. {
  311. // set up the privilege structure
  312. TOKEN_PRIVILEGES tpNewPrivileges;
  313. tpNewPrivileges.PrivilegeCount = 1;
  314. tpNewPrivileges.Privileges[0].Luid = luid;
  315. tpNewPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  316. // turn on the privilege
  317. AdjustTokenPrivileges (hToken, FALSE, &tpNewPrivileges, 0,
  318. NULL, NULL);
  319. if (ERROR_SUCCESS != GetLastError())
  320. {
  321. fWin32Success = FALSE;
  322. }
  323. }
  324. CloseHandle(hToken);
  325. }
  326. HRESULT hr;
  327. // Convert any errors to an HRESULT
  328. if (!fWin32Success)
  329. {
  330. hr = HrFromLastWin32Error();
  331. }
  332. else
  333. {
  334. hr = S_OK;
  335. }
  336. TraceError ("HrEnablePrivilege", hr);
  337. return hr;
  338. }
  339. //+---------------------------------------------------------------------------
  340. //
  341. // Function: HrEnableAllPrivileges
  342. //
  343. // Purpose: Enables all privileges for the current process.
  344. //
  345. // Arguments:
  346. // pptpOld [out] Returns the previous state of privileges so that they can
  347. // be restored.
  348. //
  349. // Returns: S_OK if successful, Win32 Error otherwise
  350. //
  351. // Author: danielwe 11 Aug 1997
  352. //
  353. // Notes: The pptpOld parameter should be freed with delete [].
  354. //
  355. HRESULT
  356. HrEnableAllPrivileges (
  357. TOKEN_PRIVILEGES** pptpOld)
  358. {
  359. Assert(pptpOld);
  360. HRESULT hr = S_OK;
  361. HANDLE hTok;
  362. ULONG cbTok = 4096;
  363. BOOL fres;
  364. // Try opening the thread token first in case of impersonation
  365. fres = OpenThreadToken(GetCurrentThread(),
  366. TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, TRUE, &hTok);
  367. if (!fres && (ERROR_NO_TOKEN == GetLastError()))
  368. {
  369. // If there was no thread token open the process token
  370. fres = OpenProcessToken(GetCurrentProcess(),
  371. TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
  372. &hTok);
  373. }
  374. if (fres)
  375. {
  376. PTOKEN_PRIVILEGES ptpNew;
  377. hr = E_OUTOFMEMORY;
  378. ptpNew = (PTOKEN_PRIVILEGES)MemAlloc(cbTok);
  379. if (ptpNew)
  380. {
  381. hr = S_OK;
  382. fres = GetTokenInformation(hTok, TokenPrivileges,
  383. ptpNew, cbTok, &cbTok);
  384. if (fres)
  385. {
  386. //
  387. // Set the state settings so that all privileges are enabled...
  388. //
  389. if (ptpNew->PrivilegeCount > 0)
  390. {
  391. for (ULONG iPriv = 0; iPriv < ptpNew->PrivilegeCount; iPriv++)
  392. {
  393. ptpNew->Privileges[iPriv].Attributes = SE_PRIVILEGE_ENABLED;
  394. }
  395. }
  396. *pptpOld = reinterpret_cast<PTOKEN_PRIVILEGES>(new BYTE[cbTok]);
  397. fres = AdjustTokenPrivileges(hTok, FALSE, ptpNew, cbTok, *pptpOld,
  398. &cbTok);
  399. }
  400. MemFree(ptpNew);
  401. }
  402. CloseHandle(hTok);
  403. }
  404. if (!fres)
  405. {
  406. hr = HrFromLastWin32Error();
  407. }
  408. TraceError("HrEnableAllPrivileges", hr);
  409. return hr;
  410. }
  411. //+---------------------------------------------------------------------------
  412. //
  413. // Function: HrRestorePrivileges
  414. //
  415. // Purpose: Restores the privileges for the current process after they have
  416. // have been modified by HrEnableAllPrivileges().
  417. //
  418. // Arguments:
  419. // ptpRestore [in] Previous state of privileges as returned by
  420. // HrEnableAllPrivileges().
  421. //
  422. // Returns: S_OK if successful, Win32 Error otherwise
  423. //
  424. // Author: danielwe 11 Aug 1997
  425. //
  426. // Notes:
  427. //
  428. HRESULT
  429. HrRestorePrivileges (
  430. TOKEN_PRIVILEGES* ptpRestore)
  431. {
  432. HRESULT hr = S_OK;
  433. HANDLE hTok = NULL ;
  434. BOOL fres = FALSE;
  435. Assert(ptpRestore);
  436. if (OpenProcessToken(GetCurrentProcess(),
  437. TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
  438. &hTok))
  439. {
  440. if (AdjustTokenPrivileges(hTok, FALSE, ptpRestore, 0, NULL, NULL))
  441. {
  442. fres = TRUE;
  443. }
  444. CloseHandle(hTok);
  445. }
  446. if (!fres)
  447. {
  448. hr = HrFromLastWin32Error();
  449. }
  450. TraceError("HrRestorePrivileges", hr);
  451. return hr;
  452. }
  453. extern const DECLSPEC_SELECTANY WCHAR c_szConnectionsPolicies[] =
  454. L"Software\\Policies\\Microsoft\\Windows\\Network Connections";
  455. // User types
  456. const DWORD USER_TYPE_ADMIN = 0x00000001;
  457. const DWORD USER_TYPE_NETCONFIGOPS = 0x00000002;
  458. const DWORD USER_TYPE_POWERUSER = 0x00000004;
  459. const DWORD USER_TYPE_USER = 0x00000008;
  460. const DWORD USER_TYPE_GUEST = 0x00000010;
  461. typedef struct
  462. {
  463. DWORD dwShift;
  464. PCWSTR pszValue;
  465. DWORD dwApplyMask;
  466. } PERM_MAP_STRUCT;
  467. extern const DECLSPEC_SELECTANY PERM_MAP_STRUCT USER_PERM_MAP[] =
  468. {
  469. {NCPERM_NewConnectionWizard, L"NC_NewConnectionWizard", APPLY_TO_ALL_USERS},
  470. {NCPERM_Statistics, L"NC_Statistics", APPLY_TO_ALL_USERS},
  471. {NCPERM_AddRemoveComponents, L"NC_AddRemoveComponents", APPLY_TO_ADMIN},
  472. {NCPERM_RasConnect, L"NC_RasConnect", APPLY_TO_ALL_USERS},
  473. {NCPERM_LanConnect, L"NC_LanConnect", APPLY_TO_ALL_USERS},
  474. {NCPERM_DeleteConnection, L"NC_DeleteConnection", APPLY_TO_ALL_USERS},
  475. {NCPERM_DeleteAllUserConnection, L"NC_DeleteAllUserConnection", APPLY_TO_ALL_USERS},
  476. {NCPERM_RenameConnection, L"NC_RenameConnection", APPLY_TO_ALL_USERS},
  477. {NCPERM_RenameMyRasConnection, L"NC_RenameMyRasConnection", APPLY_TO_ALL_USERS},
  478. {NCPERM_ChangeBindState, L"NC_ChangeBindState", APPLY_TO_ADMIN},
  479. {NCPERM_AdvancedSettings, L"NC_AdvancedSettings", APPLY_TO_ADMIN},
  480. {NCPERM_DialupPrefs, L"NC_DialupPrefs", APPLY_TO_ALL_USERS},
  481. {NCPERM_LanChangeProperties, L"NC_LanChangeProperties", APPLY_TO_OPS_OR_ADMIN},
  482. {NCPERM_RasChangeProperties, L"NC_RasChangeProperties", APPLY_TO_ALL_USERS},
  483. {NCPERM_LanProperties, L"NC_LanProperties", APPLY_TO_ALL_USERS},
  484. {NCPERM_RasMyProperties, L"NC_RasMyProperties", APPLY_TO_ALL_USERS},
  485. {NCPERM_RasAllUserProperties, L"NC_RasAllUserProperties", APPLY_TO_ALL_USERS},
  486. {NCPERM_ShowSharedAccessUi, L"NC_ShowSharedAccessUi", APPLY_TO_LOCATION},
  487. {NCPERM_AllowAdvancedTCPIPConfig, L"NC_AllowAdvancedTCPIPConfig", APPLY_TO_ALL_USERS},
  488. {NCPERM_PersonalFirewallConfig, L"NC_PersonalFirewallConfig", APPLY_TO_LOCATION},
  489. {NCPERM_AllowNetBridge_NLA, L"NC_AllowNetBridge_NLA", APPLY_TO_LOCATION},
  490. {NCPERM_ICSClientApp, L"NC_ICSClientApp", APPLY_TO_LOCATION},
  491. {NCPERM_EnDisComponentsAllUserRas, L"NC_EnDisComponentsAllUserRas", APPLY_TO_NON_ADMINS},
  492. {NCPERM_EnDisComponentsMyRas, L"NC_EnDisComponentsMyRas", APPLY_TO_NON_ADMINS},
  493. {NCPERM_ChangeMyRasProperties, L"NC_ChangeMyRasProperties", APPLY_TO_NON_ADMINS},
  494. {NCPERM_ChangeAllUserRasProperties, L"NC_ChangeAllUserRasProperties", APPLY_TO_NON_ADMINS},
  495. {NCPERM_RenameLanConnection, L"NC_RenameLanConnection", APPLY_TO_NON_ADMINS},
  496. {NCPERM_RenameAllUserRasConnection, L"NC_RenameAllUserRasConnection", APPLY_TO_NON_ADMINS},
  497. {NCPERM_IpcfgOperation, L"NC_IPConfigOperation", APPLY_TO_ALL_USERS},
  498. {NCPERM_Repair, L"NC_Repair", APPLY_TO_ALL_USERS},
  499. };
  500. extern const DECLSPEC_SELECTANY PERM_MAP_STRUCT MACHINE_PERM_MAP[] =
  501. {
  502. {NCPERM_ShowSharedAccessUi, L"NC_ShowSharedAccessUi", APPLY_TO_LOCATION},
  503. {NCPERM_PersonalFirewallConfig, L"NC_PersonalFirewallConfig", APPLY_TO_LOCATION},
  504. {NCPERM_ICSClientApp, L"NC_ICSClientApp", APPLY_TO_LOCATION},
  505. {NCPERM_AllowNetBridge_NLA, L"NC_AllowNetBridge_NLA", APPLY_TO_LOCATION}
  506. };
  507. extern const LONG NCPERM_Min = NCPERM_NewConnectionWizard;
  508. extern const LONG NCPERM_Max = NCPERM_Repair;
  509. // External policies (for now, only explorer has polices that affect our processing
  510. //
  511. extern const WCHAR c_szExplorerPolicies[] =
  512. L"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer";
  513. extern const WCHAR c_szNCPolicyForAdministrators[] =
  514. L"NC_EnableAdminProhibits";
  515. extern const WCHAR c_szNoNetworkConnectionPolicy[] =
  516. L"NoNetworkConnections";
  517. static DWORD g_dwPermMask;
  518. static BOOL g_fPermsInited = FALSE;
  519. inline
  520. VOID NCPERM_SETBIT(DWORD dw, DWORD dwVal)
  521. {
  522. DWORD dwBit = (1 << dw);
  523. g_dwPermMask = (g_dwPermMask & ~dwBit) | ((0==dwVal) ? 0 : dwBit);
  524. }
  525. inline
  526. BOOL NCPERM_CHECKBIT(DWORD dw)
  527. {
  528. #ifdef DBG
  529. if (!FIsPolicyConfigured(dw))
  530. {
  531. if (0xFFFFFFFF != g_dwDbgPermissionsFail)
  532. {
  533. if (FProhibitFromAdmins() || !FIsUserAdmin())
  534. {
  535. if ( (1 << dw) & g_dwDbgPermissionsFail)
  536. {
  537. TraceTag(ttidDefault, "Failing permissions check due to g_dwDbgPermissionsFail set");
  538. return FALSE;
  539. }
  540. }
  541. }
  542. }
  543. #endif // DBG
  544. return !!(g_dwPermMask & (1 << dw));
  545. }
  546. inline
  547. BOOL NCPERM_USER_IS_ADMIN(DWORD dwUserType)
  548. {
  549. return (dwUserType & USER_TYPE_ADMIN);
  550. }
  551. inline
  552. BOOL NCPERM_USER_IS_NETCONFIGOPS(DWORD dwUserType)
  553. {
  554. return (dwUserType & USER_TYPE_NETCONFIGOPS);
  555. }
  556. inline
  557. BOOL NCPERM_USER_IS_POWERUSER(DWORD dwUserType)
  558. {
  559. return (dwUserType & USER_TYPE_POWERUSER);
  560. }
  561. inline
  562. BOOL NCPERM_USER_IS_USER(DWORD dwUserType)
  563. {
  564. return (dwUserType & USER_TYPE_USER);
  565. }
  566. inline
  567. BOOL NCPERM_USER_IS_GUEST(DWORD dwUserType)
  568. {
  569. return (dwUserType & USER_TYPE_GUEST);
  570. }
  571. inline
  572. BOOL NCPERM_APPLIES_TO_CURRENT_USER(DWORD dwUserType, DWORD dwApplyMask)
  573. {
  574. return (dwUserType & dwApplyMask);
  575. }
  576. inline
  577. int NCPERM_FIND_MAP_ENTRY(ULONG ulPerm)
  578. {
  579. for (int i = 0; i < celems(USER_PERM_MAP); i++)
  580. {
  581. if (USER_PERM_MAP[i].dwShift == ulPerm)
  582. {
  583. return i;
  584. }
  585. }
  586. return -1;
  587. }
  588. inline
  589. BOOL NCPERM_APPLIES_TO_LOCATION(ULONG ulPerm)
  590. {
  591. BOOL bAppliesToLocation = FALSE;
  592. int nIdx = NCPERM_FIND_MAP_ENTRY(ulPerm);
  593. if (nIdx != -1)
  594. {
  595. bAppliesToLocation = (USER_PERM_MAP[nIdx].dwApplyMask & APPLY_TO_LOCATION);
  596. }
  597. else
  598. {
  599. bAppliesToLocation = FALSE;
  600. }
  601. return bAppliesToLocation;
  602. }
  603. inline
  604. BOOL NCPERM_APPLY_BASED_ON_LOCATION(ULONG ulPerm, DWORD dwPermission)
  605. {
  606. DWORD fSameNetwork = FALSE;
  607. if (g_pNetmanGPNLA)
  608. {
  609. fSameNetwork = g_pNetmanGPNLA->IsSameNetworkAsGroupPolicies();
  610. }
  611. if (!fSameNetwork && NCPERM_APPLIES_TO_LOCATION(ulPerm))
  612. {
  613. dwPermission = TRUE;
  614. }
  615. return dwPermission;
  616. }
  617. inline
  618. DWORD NCPERM_USER_TYPE()
  619. {
  620. if (FIsUserAdmin())
  621. {
  622. return USER_TYPE_ADMIN;
  623. }
  624. else if (FIsUserNetworkConfigOps())
  625. {
  626. return USER_TYPE_NETCONFIGOPS;
  627. }
  628. else if (FIsUserPowerUser())
  629. {
  630. return USER_TYPE_POWERUSER;
  631. }
  632. else if (FIsUserGuest())
  633. {
  634. return USER_TYPE_GUEST;
  635. }
  636. return USER_TYPE_USER;
  637. }
  638. inline
  639. BOOL IsOsLikePersonal()
  640. {
  641. OSVERSIONINFOEXW verInfo = {0};
  642. ULONGLONG ConditionMask = 0;
  643. static BOOL fChecked = FALSE;
  644. static BOOL fOsLikePersonal = FALSE;
  645. // Optimization, since OS can't change on the fly. Even a domain join requires a reboot.
  646. // If that ever changes then this logic needs to be revisited.
  647. if (fChecked)
  648. {
  649. return fOsLikePersonal;
  650. }
  651. verInfo.dwOSVersionInfoSize = sizeof(verInfo);
  652. verInfo.wProductType = VER_NT_WORKSTATION;
  653. VER_SET_CONDITION(ConditionMask, VER_PRODUCT_TYPE, VER_LESS_EQUAL);
  654. if(VerifyVersionInfo(&verInfo, VER_PRODUCT_TYPE, ConditionMask))
  655. {
  656. LPWSTR pszDomain;
  657. NETSETUP_JOIN_STATUS njs = NetSetupUnknownStatus;
  658. if (NERR_Success == NetGetJoinInformation(NULL, &pszDomain, &njs))
  659. {
  660. NetApiBufferFree(pszDomain);
  661. }
  662. if (NetSetupDomainName == njs)
  663. {
  664. fOsLikePersonal = FALSE; // connected to domain
  665. }
  666. else
  667. {
  668. fOsLikePersonal = TRUE; // Professional, but not a domain member
  669. }
  670. }
  671. else
  672. {
  673. fOsLikePersonal = FALSE;
  674. }
  675. fChecked = TRUE;
  676. return fOsLikePersonal;
  677. }
  678. const ULONG c_arrayHomenetPerms[] =
  679. {
  680. NCPERM_PersonalFirewallConfig,
  681. NCPERM_AllowNetBridge_NLA,
  682. NCPERM_ICSClientApp,
  683. NCPERM_ShowSharedAccessUi
  684. };
  685. #ifdef DBG
  686. ULONG g_dwDbgPermissionsFail = 0xFFFFFFFF;
  687. ULONG g_dwDbgWin2kPoliciesSet = 0xFFFFFFFF;
  688. #endif // DBG
  689. //+---------------------------------------------------------------------------
  690. //
  691. // Function: FHasPermission
  692. //
  693. // Purpose: Called to determine if the requested permissions are available
  694. //
  695. // Arguments:
  696. // ulPerm [in] permission flags
  697. //
  698. // Returns: BOOL, TRUE if the requested permission is granted to the user
  699. //
  700. BOOL
  701. FHasPermission(ULONG ulPerm, CGroupPolicyBase* pGPBase)
  702. {
  703. TraceFileFunc(ttidDefault);
  704. DWORD dwCurrentUserType;
  705. Assert(static_cast<LONG>(ulPerm) >= NCPERM_Min);
  706. Assert(static_cast<LONG>(ulPerm) <= NCPERM_Max);
  707. g_pNetmanGPNLA = pGPBase;
  708. //if the requested is from a homenet component and we are using DataCenter or
  709. //Advanced Server, than dont grant the permission
  710. for (int i = 0; i < celems(c_arrayHomenetPerms); i++)
  711. {
  712. if (c_arrayHomenetPerms[i] == ulPerm)
  713. {
  714. // On IA64, all homenet technologies are unavailable.
  715. #ifndef _WIN64
  716. // Look for the enterprise SKUs
  717. OSVERSIONINFOEXW verInfo = {0};
  718. ULONGLONG ConditionMask = 0;
  719. verInfo.dwOSVersionInfoSize = sizeof(verInfo);
  720. verInfo.wSuiteMask = VER_SUITE_ENTERPRISE;
  721. VER_SET_CONDITION(ConditionMask, VER_SUITENAME, VER_AND);
  722. if(VerifyVersionInfo(&verInfo, VER_SUITENAME, ConditionMask))
  723. #endif
  724. {
  725. return FALSE;
  726. }
  727. }
  728. }
  729. dwCurrentUserType = NCPERM_USER_TYPE();
  730. if (NCPERM_USER_IS_ADMIN(dwCurrentUserType) && !FProhibitFromAdmins() && !NCPERM_APPLIES_TO_LOCATION(ulPerm))
  731. {
  732. // If user is admin and we're not supposed to revoke
  733. // anything from admins and this is not a location aware policy
  734. // then just return TRUE
  735. return TRUE;
  736. }
  737. if (!g_fPermsInited)
  738. {
  739. TraceTag(ttidDefault, "Initializing permissions");
  740. g_fPermsInited = TRUE;
  741. RefreshAllPermission();
  742. }
  743. else
  744. {
  745. // update the requested permission only
  746. HRESULT hr = S_OK;
  747. HKEY hkey = NULL;
  748. DWORD dw = 0;
  749. switch(ulPerm)
  750. {
  751. case NCPERM_OpenConnectionsFolder:
  752. TraceTag(ttidDefault, "Reading OpenConnectionsFolder permissions");
  753. hr = HrRegOpenKeyEx(HKEY_CURRENT_USER, c_szExplorerPolicies,
  754. KEY_READ, &hkey);
  755. if (S_OK == hr)
  756. {
  757. TraceTag(ttidDefault, "Opened explorer policies");
  758. hr = HrRegQueryDword(hkey, c_szNoNetworkConnectionPolicy, &dw);
  759. if (SUCCEEDED(hr) && dw)
  760. {
  761. TraceTag(ttidDefault,
  762. "Explorer 'No open connections folder' policy: %d", dw);
  763. NCPERM_SETBIT(NCPERM_OpenConnectionsFolder, 0);
  764. }
  765. RegCloseKey(hkey);
  766. hkey = NULL;
  767. }
  768. break;
  769. default:
  770. hr = HrRegOpenKeyEx(HKEY_CURRENT_USER, c_szConnectionsPolicies,
  771. KEY_READ, &hkey);
  772. if (S_OK == hr)
  773. {
  774. DWORD dw;
  775. // Read the User Policy
  776. for (UINT nIdx=0; nIdx<celems(USER_PERM_MAP); nIdx++)
  777. {
  778. if (ulPerm == USER_PERM_MAP[nIdx].dwShift && NCPERM_APPLIES_TO_CURRENT_USER(dwCurrentUserType, USER_PERM_MAP[nIdx].dwApplyMask))
  779. {
  780. hr = HrRegQueryDword(hkey, USER_PERM_MAP[nIdx].pszValue, &dw);
  781. if (SUCCEEDED(hr))
  782. {
  783. NCPERM_SETBIT(USER_PERM_MAP[nIdx].dwShift, dw);
  784. }
  785. }
  786. }
  787. RegCloseKey(hkey);
  788. }
  789. // Read the machine policy
  790. //
  791. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szConnectionsPolicies,
  792. KEY_READ, &hkey);
  793. if (S_OK == hr)
  794. {
  795. DWORD dw;
  796. for (UINT nIdx=0; nIdx<celems(MACHINE_PERM_MAP); nIdx++)
  797. {
  798. if (ulPerm == MACHINE_PERM_MAP[nIdx].dwShift)
  799. {
  800. hr = HrRegQueryDword(hkey, MACHINE_PERM_MAP[nIdx].pszValue, &dw);
  801. if (S_OK == hr)
  802. {
  803. NCPERM_SETBIT(MACHINE_PERM_MAP[nIdx].dwShift, NCPERM_APPLY_BASED_ON_LOCATION(ulPerm, dw));
  804. }
  805. }
  806. }
  807. RegCloseKey(hkey);
  808. }
  809. break;
  810. }
  811. }
  812. return NCPERM_CHECKBIT(ulPerm);
  813. }
  814. BOOL
  815. FHasPermissionFromCache(ULONG ulPerm)
  816. {
  817. Assert(static_cast<LONG>(ulPerm) >= NCPERM_Min);
  818. Assert(static_cast<LONG>(ulPerm) <= NCPERM_Max);
  819. if (!g_fPermsInited)
  820. {
  821. g_fPermsInited = TRUE;
  822. RefreshAllPermission();
  823. }
  824. return NCPERM_CHECKBIT(ulPerm);
  825. }
  826. //+---------------------------------------------------------------------------
  827. //
  828. // Function: HrRestorePrivileges
  829. //
  830. // Purpose: Restores the privileges for the current process after they have
  831. // have been modified by HrEnableAllPrivileges().
  832. //
  833. // Arguments:
  834. // ptpRestore [in] Previous state of privileges as returned by
  835. // HrEnableAllPrivileges().
  836. //
  837. // Returns: S_OK if successful, Win32 Error otherwise
  838. //
  839. // Author: danielwe 11 Aug 1997
  840. //
  841. // Notes:
  842. //
  843. BOOL FProhibitFromAdmins()
  844. {
  845. HRESULT hr = S_OK;
  846. HKEY hKey;
  847. DWORD dw;
  848. BOOL bEnabled = FALSE;
  849. #ifdef DBG
  850. if (0xFFFFFFFF != g_dwDbgWin2kPoliciesSet)
  851. {
  852. return g_dwDbgWin2kPoliciesSet;
  853. }
  854. #endif // DBG
  855. hr = HrRegOpenKeyEx(HKEY_CURRENT_USER, c_szConnectionsPolicies,
  856. KEY_READ, &hKey);
  857. if (S_OK == hr)
  858. {
  859. hr = HrRegQueryDword(hKey, c_szNCPolicyForAdministrators, &dw);
  860. bEnabled = (dw) ? TRUE : FALSE;
  861. RegCloseKey(hKey);
  862. }
  863. TraceErrorOptional("FProhibitFromAdmins", hr, (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr));
  864. return bEnabled;
  865. }
  866. VOID RefreshAllPermission()
  867. {
  868. DWORD dwCurrentUserType;
  869. HKEY hkey;
  870. HRESULT hr;
  871. DWORD dw;
  872. dwCurrentUserType = NCPERM_USER_TYPE();
  873. g_dwPermMask = 0;
  874. // If Admin assume all rights
  875. //
  876. if (NCPERM_USER_IS_ADMIN(dwCurrentUserType))
  877. {
  878. // Cheat a little by setting all bits to one
  879. //
  880. g_dwPermMask = 0xFFFFFFFF;
  881. // If this policy is not set, then we don't need to worry about reading the regkeys
  882. // since we can never take anything away from Admins.
  883. }
  884. else if (NCPERM_USER_IS_NETCONFIGOPS(dwCurrentUserType))
  885. {
  886. NCPERM_SETBIT(NCPERM_NewConnectionWizard, 1);
  887. NCPERM_SETBIT(NCPERM_Statistics, 1);
  888. NCPERM_SETBIT(NCPERM_RasConnect, 1);
  889. NCPERM_SETBIT(NCPERM_DeleteConnection, 1);
  890. NCPERM_SETBIT(NCPERM_DeleteAllUserConnection, 1);
  891. NCPERM_SETBIT(NCPERM_RenameConnection, 1);
  892. NCPERM_SETBIT(NCPERM_RenameMyRasConnection, 1);
  893. NCPERM_SETBIT(NCPERM_RenameAllUserRasConnection, 1);
  894. NCPERM_SETBIT(NCPERM_RenameLanConnection, 1);
  895. NCPERM_SETBIT(NCPERM_DialupPrefs, 1);
  896. NCPERM_SETBIT(NCPERM_RasChangeProperties, 1);
  897. NCPERM_SETBIT(NCPERM_RasMyProperties, 1);
  898. NCPERM_SETBIT(NCPERM_RasAllUserProperties, 1);
  899. NCPERM_SETBIT(NCPERM_ChangeAllUserRasProperties, 1);
  900. NCPERM_SETBIT(NCPERM_LanProperties, 1);
  901. NCPERM_SETBIT(NCPERM_LanChangeProperties, 1);
  902. NCPERM_SETBIT(NCPERM_AllowAdvancedTCPIPConfig, 1);
  903. NCPERM_SETBIT(NCPERM_OpenConnectionsFolder, 1);
  904. NCPERM_SETBIT(NCPERM_LanConnect, 1);
  905. NCPERM_SETBIT(NCPERM_EnDisComponentsAllUserRas, 1);
  906. NCPERM_SETBIT(NCPERM_EnDisComponentsMyRas, 1);
  907. NCPERM_SETBIT(NCPERM_IpcfgOperation, 1);
  908. NCPERM_SETBIT(NCPERM_Repair, 1);
  909. }
  910. else if (NCPERM_USER_IS_POWERUSER(dwCurrentUserType))
  911. {
  912. NCPERM_SETBIT(NCPERM_Repair, 1);
  913. // Rest should be like NCPERM_USER_IS_USER
  914. NCPERM_SETBIT(NCPERM_NewConnectionWizard, 1);
  915. NCPERM_SETBIT(NCPERM_Statistics, 1);
  916. NCPERM_SETBIT(NCPERM_RasConnect, 1);
  917. NCPERM_SETBIT(NCPERM_DeleteConnection, 1);
  918. NCPERM_SETBIT(NCPERM_RenameMyRasConnection, 1);
  919. NCPERM_SETBIT(NCPERM_DialupPrefs, 1);
  920. NCPERM_SETBIT(NCPERM_RasChangeProperties, 1);
  921. NCPERM_SETBIT(NCPERM_RasMyProperties, 1);
  922. NCPERM_SETBIT(NCPERM_AllowAdvancedTCPIPConfig, 1);
  923. NCPERM_SETBIT(NCPERM_LanProperties, 1);
  924. NCPERM_SETBIT(NCPERM_OpenConnectionsFolder, 1);
  925. if (IsOsLikePersonal())
  926. {
  927. NCPERM_SETBIT(NCPERM_RasAllUserProperties, 1);
  928. NCPERM_SETBIT(NCPERM_ChangeAllUserRasProperties, 1);
  929. }
  930. }
  931. else if (NCPERM_USER_IS_USER(dwCurrentUserType))
  932. {
  933. NCPERM_SETBIT(NCPERM_NewConnectionWizard, 1);
  934. NCPERM_SETBIT(NCPERM_Statistics, 1);
  935. NCPERM_SETBIT(NCPERM_RasConnect, 1);
  936. NCPERM_SETBIT(NCPERM_DeleteConnection, 1);
  937. NCPERM_SETBIT(NCPERM_RenameMyRasConnection, 1);
  938. NCPERM_SETBIT(NCPERM_DialupPrefs, 1);
  939. NCPERM_SETBIT(NCPERM_RasChangeProperties, 1);
  940. NCPERM_SETBIT(NCPERM_RasMyProperties, 1);
  941. NCPERM_SETBIT(NCPERM_AllowAdvancedTCPIPConfig, 1);
  942. NCPERM_SETBIT(NCPERM_LanProperties, 1);
  943. NCPERM_SETBIT(NCPERM_OpenConnectionsFolder, 1);
  944. if (IsOsLikePersonal())
  945. {
  946. NCPERM_SETBIT(NCPERM_RasAllUserProperties, 1);
  947. NCPERM_SETBIT(NCPERM_ChangeAllUserRasProperties, 1);
  948. }
  949. }
  950. else if (NCPERM_USER_IS_GUEST(dwCurrentUserType))
  951. {
  952. NCPERM_SETBIT(NCPERM_Statistics, 1);
  953. NCPERM_SETBIT(NCPERM_OpenConnectionsFolder, 1);
  954. }
  955. if (FProhibitFromAdmins() || !NCPERM_USER_IS_ADMIN(dwCurrentUserType))
  956. {
  957. // Read folder policy
  958. hr = HrRegOpenKeyEx(HKEY_CURRENT_USER, c_szExplorerPolicies,
  959. KEY_READ, &hkey);
  960. if (S_OK == hr)
  961. {
  962. TraceTag(ttidDefault, "Opened Explorer Policy reg key");
  963. hr = HrRegQueryDword(hkey, c_szNoNetworkConnectionPolicy, &dw);
  964. if (SUCCEEDED(hr) && dw)
  965. {
  966. TraceTag(ttidDefault, "Explorer 'No open connections folder' policy: %d", dw);
  967. NCPERM_SETBIT(NCPERM_OpenConnectionsFolder, 0);
  968. }
  969. RegCloseKey(hkey);
  970. hkey = NULL;
  971. }
  972. // Read the user policy
  973. //
  974. hr = HrRegOpenKeyEx(HKEY_CURRENT_USER, c_szConnectionsPolicies,
  975. KEY_READ, &hkey);
  976. if (S_OK == hr)
  977. {
  978. for (UINT nIdx=0; nIdx<celems(USER_PERM_MAP); nIdx++)
  979. {
  980. if (NCPERM_APPLIES_TO_CURRENT_USER(dwCurrentUserType, USER_PERM_MAP[nIdx].dwApplyMask))
  981. {
  982. hr = HrRegQueryDword(hkey, USER_PERM_MAP[nIdx].pszValue, &dw);
  983. if (SUCCEEDED(hr))
  984. {
  985. NCPERM_SETBIT(USER_PERM_MAP[nIdx].dwShift, dw);
  986. }
  987. }
  988. }
  989. RegCloseKey(hkey);
  990. }
  991. }
  992. // Read the machine policy
  993. //
  994. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szConnectionsPolicies,
  995. KEY_READ, &hkey);
  996. if (S_OK == hr)
  997. {
  998. DWORD dw;
  999. for (UINT nIdx=0; nIdx<celems(MACHINE_PERM_MAP); nIdx++)
  1000. {
  1001. hr = HrRegQueryDword(hkey, MACHINE_PERM_MAP[nIdx].pszValue, &dw);
  1002. if (S_OK == hr)
  1003. {
  1004. NCPERM_SETBIT(MACHINE_PERM_MAP[nIdx].dwShift, NCPERM_APPLY_BASED_ON_LOCATION(MACHINE_PERM_MAP[nIdx].dwShift, dw));
  1005. }
  1006. }
  1007. RegCloseKey(hkey);
  1008. }
  1009. }
  1010. //+---------------------------------------------------------------------------
  1011. //
  1012. // Function: IsHNetAllowed
  1013. //
  1014. // Purpose: Verify the permission to use/enable (ICS/Firewall and create bridge network)
  1015. //
  1016. // Checks the following:
  1017. //
  1018. // Does the architecture / SKU permit the use of homenet technologies?
  1019. // Does group policy allow the particular technology?
  1020. // Is the user an Admin and are admins allowed access to this technology?
  1021. //
  1022. // Example scenario. The user is a Admin but ITG disables the right to create bridge this function would return FALSE
  1023. //
  1024. BOOL
  1025. IsHNetAllowed(
  1026. DWORD dwPerm
  1027. )
  1028. {
  1029. #ifndef _WIN64
  1030. BOOL fPermission = false;
  1031. OSVERSIONINFOEXW verInfo = {0};
  1032. ULONGLONG ConditionMask = 0;
  1033. // Look for the enterprise SKUs
  1034. verInfo.dwOSVersionInfoSize = sizeof(verInfo);
  1035. verInfo.wSuiteMask = VER_SUITE_ENTERPRISE;
  1036. VER_SET_CONDITION(ConditionMask, VER_SUITENAME, VER_AND);
  1037. if ( VerifyVersionInfo(&verInfo, VER_SUITENAME, ConditionMask) )
  1038. {
  1039. // Homenet technologies are not available on enterprise SKUs
  1040. return FALSE;
  1041. }
  1042. if ( FIsUserAdmin() && !FProhibitFromAdmins() )
  1043. {
  1044. HRESULT hr;
  1045. INetMachinePolicies* pMachinePolicy;
  1046. hr = CoCreateInstance(
  1047. CLSID_NetGroupPolicies,
  1048. NULL,
  1049. CLSCTX_SERVER,
  1050. IID_INetMachinePolicies,
  1051. reinterpret_cast<void **>(&pMachinePolicy)
  1052. );
  1053. if ( SUCCEEDED(hr) )
  1054. {
  1055. hr = pMachinePolicy->VerifyPermission(dwPerm, &fPermission);
  1056. pMachinePolicy->Release();
  1057. }
  1058. }
  1059. return fPermission;
  1060. #else // #ifndef _WIN64
  1061. // On IA64, homenet technologies are not available at all.
  1062. return FALSE;
  1063. #endif
  1064. }
  1065. //+---------------------------------------------------------------------------
  1066. //
  1067. // Function: FIsUserNetworkConfigOps
  1068. //
  1069. // Purpose: Checks to see if the current user is a NetConfig Operator
  1070. //
  1071. //
  1072. // Arguments:
  1073. // none.
  1074. //
  1075. //
  1076. // Returns: BOOL.
  1077. //
  1078. // Author: ckotze 12 Jun 2000
  1079. //
  1080. // Notes:
  1081. //
  1082. BOOL FIsUserNetworkConfigOps()
  1083. {
  1084. BOOL fIsMember;
  1085. fIsMember = FCheckGroupMembership(DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS);
  1086. return fIsMember;
  1087. }
  1088. //+---------------------------------------------------------------------------
  1089. //
  1090. // Function: FIsUserPowerUser
  1091. //
  1092. // Purpose: Checks to see if the current user is a Power User
  1093. //
  1094. //
  1095. // Arguments:
  1096. // none.
  1097. //
  1098. //
  1099. // Returns: BOOL.
  1100. //
  1101. // Author: deonb 9 May 2001
  1102. //
  1103. // Notes:
  1104. //
  1105. BOOL FIsUserPowerUser()
  1106. {
  1107. BOOL fIsMember;
  1108. fIsMember = FCheckGroupMembership(DOMAIN_ALIAS_RID_POWER_USERS);
  1109. return fIsMember;
  1110. }
  1111. //+---------------------------------------------------------------------------
  1112. //
  1113. // Function: FIsUserGuest
  1114. //
  1115. // Purpose: Checks to see if the current user is a Guest
  1116. //
  1117. //
  1118. // Arguments:
  1119. // none.
  1120. //
  1121. //
  1122. // Returns: BOOL.
  1123. //
  1124. // Author: ckotze 12 Jun 2000
  1125. //
  1126. // Notes:
  1127. //
  1128. BOOL FIsUserGuest()
  1129. {
  1130. BOOL fIsMember;
  1131. fIsMember = FCheckGroupMembership(DOMAIN_ALIAS_RID_GUESTS);
  1132. return fIsMember;
  1133. }
  1134. //+---------------------------------------------------------------------------
  1135. //
  1136. // Function: FIsPolicyConfigured
  1137. //
  1138. // Purpose: Checks to see if the specific policy is configured
  1139. //
  1140. //
  1141. // Arguments:
  1142. // none.
  1143. //
  1144. //
  1145. // Returns: BOOL.
  1146. //
  1147. // Author: ckotze 12 Jun 2000
  1148. //
  1149. // Notes:
  1150. //
  1151. BOOL FIsPolicyConfigured(DWORD ulPerm)
  1152. {
  1153. HRESULT hr;
  1154. HKEY hkey;
  1155. BOOL bConfigured = FALSE;
  1156. hr = HrRegOpenKeyEx(HKEY_CURRENT_USER, c_szConnectionsPolicies, KEY_READ, &hkey);
  1157. if (S_OK == hr)
  1158. {
  1159. DWORD dw;
  1160. if (ulPerm == USER_PERM_MAP[ulPerm].dwShift)
  1161. {
  1162. DWORD dw;
  1163. hr = HrRegQueryDword(hkey, USER_PERM_MAP[static_cast<DWORD>(ulPerm)].pszValue, &dw);
  1164. if (SUCCEEDED(hr))
  1165. {
  1166. bConfigured = TRUE;
  1167. }
  1168. }
  1169. RegCloseKey(hkey);
  1170. }
  1171. return bConfigured;
  1172. }
  1173. //+---------------------------------------------------------------------------
  1174. //
  1175. // Function: IsSameNetworkAsGroupPolicies
  1176. //
  1177. // Purpose: Checks to see if the current network is the same as where the
  1178. // Group Policies were assigned from.
  1179. //
  1180. // Arguments:
  1181. // none.
  1182. //
  1183. //
  1184. // Returns: BOOL
  1185. //
  1186. // Author: ckotze 05 Jan 2001
  1187. //
  1188. // Notes:
  1189. //
  1190. BOOL IsSameNetworkAsGroupPolicies()
  1191. {
  1192. return g_pNetmanGPNLA->IsSameNetworkAsGroupPolicies();
  1193. }