Leaked source code of windows server 2003
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.

330 lines
8.2 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. Security.cpp
  5. Abstract:
  6. General fax server security utility functions
  7. Author:
  8. Eran Yariv (EranY) Feb, 2001
  9. Revision History:
  10. --*/
  11. #include <windows.h>
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <tchar.h>
  15. #include <Accctrl.h>
  16. #include <Aclapi.h>
  17. #include "faxutil.h"
  18. #include "faxreg.h"
  19. #include "FaxUIConstants.h"
  20. HANDLE
  21. EnablePrivilege (
  22. LPCTSTR lpctstrPrivName
  23. )
  24. /*++
  25. Routine name : EnablePrivilege
  26. Routine description:
  27. Enables a specific privilege in the current thread (or process) access token
  28. Author:
  29. Eran Yariv (EranY), Feb, 2001
  30. Arguments:
  31. lpctstrPrivName [in] - Privilege to enable (e.g. SE_TAKE_OWNERSHIP_NAME)
  32. Return Value:
  33. INVALID_HANDLE_VALUE on failure (call GetLastError to get error code).
  34. On success, returns the handle which holds the thread/process priviledges before the change.
  35. The caller must call ReleasePrivilege() to restore the access token state and release the handle.
  36. --*/
  37. {
  38. BOOL fResult;
  39. HANDLE hToken = INVALID_HANDLE_VALUE;
  40. HANDLE hOriginalThreadToken = INVALID_HANDLE_VALUE;
  41. LUID luidPriv;
  42. TOKEN_PRIVILEGES tp = {0};
  43. DEBUG_FUNCTION_NAME( TEXT("EnablePrivileges"));
  44. Assert (lpctstrPrivName);
  45. //
  46. // Get the LUID of the privilege.
  47. //
  48. if (!LookupPrivilegeValue(NULL,
  49. lpctstrPrivName,
  50. &luidPriv))
  51. {
  52. DebugPrintEx(
  53. DEBUG_ERR,
  54. _T("Failed to LookupPrivilegeValue. (ec: %ld)"),
  55. GetLastError ());
  56. return INVALID_HANDLE_VALUE;
  57. }
  58. //
  59. // Initialize the Privileges Structure
  60. //
  61. tp.PrivilegeCount = 1;
  62. tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  63. tp.Privileges[0].Luid = luidPriv;
  64. //
  65. // Open the Token
  66. //
  67. fResult = OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE, FALSE, &hToken);
  68. if (fResult)
  69. {
  70. //
  71. // Remember the thread token
  72. //
  73. hOriginalThreadToken = hToken;
  74. }
  75. else
  76. {
  77. fResult = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &hToken);
  78. }
  79. if (fResult)
  80. {
  81. HANDLE hNewToken;
  82. //
  83. // Duplicate that Token
  84. //
  85. fResult = DuplicateTokenEx(hToken,
  86. TOKEN_IMPERSONATE | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
  87. NULL, // PSECURITY_ATTRIBUTES
  88. SecurityImpersonation, // SECURITY_IMPERSONATION_LEVEL
  89. TokenImpersonation, // TokenType
  90. &hNewToken); // Duplicate token
  91. if (fResult)
  92. {
  93. //
  94. // Add new privileges
  95. //
  96. fResult = AdjustTokenPrivileges(hNewToken, // TokenHandle
  97. FALSE, // DisableAllPrivileges
  98. &tp, // NewState
  99. 0, // BufferLength
  100. NULL, // PreviousState
  101. NULL); // ReturnLength
  102. if (fResult)
  103. {
  104. //
  105. // Begin impersonating with the new token
  106. //
  107. fResult = SetThreadToken(NULL, hNewToken);
  108. }
  109. CloseHandle(hNewToken);
  110. }
  111. }
  112. //
  113. // If something failed, don't return a token
  114. //
  115. if (!fResult)
  116. {
  117. hOriginalThreadToken = INVALID_HANDLE_VALUE;
  118. }
  119. if (INVALID_HANDLE_VALUE == hOriginalThreadToken)
  120. {
  121. //
  122. // Using the process token
  123. //
  124. if (INVALID_HANDLE_VALUE != hToken)
  125. {
  126. //
  127. // Close the original token if we aren't returning it
  128. //
  129. CloseHandle(hToken);
  130. }
  131. if (fResult)
  132. {
  133. //
  134. // If we succeeded, but there was no original thread token,
  135. // return NULL to indicate we need to do SetThreadToken(NULL, NULL) to release privs.
  136. //
  137. hOriginalThreadToken = NULL;
  138. }
  139. }
  140. return hOriginalThreadToken;
  141. } // EnablePrivilege
  142. void
  143. ReleasePrivilege(
  144. HANDLE hToken
  145. )
  146. /*++
  147. Routine name : ReleasePrivilege
  148. Routine description:
  149. Resets privileges to the state prior to the corresponding EnablePrivilege() call
  150. Author:
  151. Eran Yariv (EranY), Feb, 2001
  152. Arguments:
  153. hToken [IN] - Return value from the corresponding EnablePrivilege() call
  154. Return Value:
  155. None.
  156. --*/
  157. {
  158. DEBUG_FUNCTION_NAME( TEXT("ReleasePrivilege"));
  159. if (INVALID_HANDLE_VALUE != hToken)
  160. {
  161. if(!SetThreadToken(NULL, hToken))
  162. {
  163. DebugPrintEx(DEBUG_ERR, TEXT("SetThreadToken() failed (ec: %ld)"), GetLastError());
  164. }
  165. if (hToken)
  166. {
  167. if(!CloseHandle(hToken))
  168. {
  169. DebugPrintEx(DEBUG_ERR, TEXT("CloseHandle() failed (ec: %ld)"), GetLastError());
  170. }
  171. }
  172. }
  173. } // ReleasePrivilege
  174. DWORD
  175. EnableProcessPrivilege(LPCTSTR lpPrivilegeName)
  176. /*++
  177. Routine name : EnableProcessPrivilege
  178. Routine description:
  179. Enables process privilege.
  180. Author:
  181. Caliv Nir (t-nicali) Mar, 2002
  182. Arguments:
  183. lpPrivilegeName [in] - Pointer to a null-terminated string that specifies the name of the privilege,
  184. as defined in the Winnt.h header file. For example,
  185. this parameter could specify the constant SE_SECURITY_NAME,
  186. or its corresponding string, "SeSecurityPrivilege"
  187. Return Value:
  188. Standard Win32 error code.
  189. --*/
  190. {
  191. HANDLE hToken = INVALID_HANDLE_VALUE;
  192. TOKEN_PRIVILEGES tp = {0};
  193. LUID luidPriv;
  194. BOOL bRet;
  195. DWORD dwRet=ERROR_SUCCESS;
  196. DEBUG_FUNCTION_NAME( TEXT("EnableProcessPrivilege"));
  197. Assert(lpPrivilegeName);
  198. //
  199. // Get the LUID of the privilege.
  200. //
  201. if (!LookupPrivilegeValue(NULL,
  202. lpPrivilegeName,
  203. &luidPriv))
  204. {
  205. dwRet = GetLastError();
  206. DebugPrintEx(
  207. DEBUG_ERR,
  208. _T("Failed to LookupPrivilegeValue. (ec: %lu)"),
  209. dwRet);
  210. goto Exit;
  211. }
  212. //
  213. // Initialize the Privileges Structure
  214. //
  215. tp.PrivilegeCount = 1;
  216. tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  217. tp.Privileges[0].Luid = luidPriv;
  218. //
  219. // Open process token
  220. //
  221. bRet = OpenProcessToken(GetCurrentProcess(),
  222. TOKEN_ADJUST_PRIVILEGES,
  223. &hToken);
  224. if (FALSE == bRet)
  225. {
  226. //
  227. // Failed to OpenProcessToken
  228. //
  229. dwRet = GetLastError();
  230. DebugPrintEx(
  231. DEBUG_ERR,
  232. TEXT("OpenProcessToken() failed: err = %lu"),
  233. dwRet);
  234. goto Exit;
  235. }
  236. //
  237. // Adjust the Token
  238. //
  239. bRet = AdjustTokenPrivileges(hToken, // TokenHandle
  240. FALSE, // DisableAllPrivileges
  241. &tp, // NewState
  242. 0, // BufferLength
  243. NULL, // PreviousState
  244. NULL); // ReturnLength
  245. if (FALSE == bRet)
  246. {
  247. //
  248. // Failed to OpenProcessToken
  249. //
  250. dwRet = GetLastError();
  251. DebugPrintEx(
  252. DEBUG_ERR,
  253. TEXT("AdjustTokenPrivileges() failed: err = %lu"),
  254. dwRet);
  255. goto Exit;
  256. }
  257. Assert(ERROR_SUCCESS == dwRet);
  258. Exit:
  259. if(NULL != hToken)
  260. {
  261. if(!CloseHandle(hToken))
  262. {
  263. DebugPrintEx(
  264. DEBUG_ERR,
  265. TEXT("CloseHandle() failed: err = %lu"),
  266. GetLastError());
  267. }
  268. }
  269. return dwRet;
  270. }