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.

382 lines
12 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: winstl/security/token_information.hpp
  3. *
  4. * Purpose: Helper for accessing token information.
  5. *
  6. * Created: 20th June 2003
  7. * Updated: 10th August 2009
  8. *
  9. * Home: http://stlsoft.org/
  10. *
  11. * Copyright (c) 2003-2009, Matthew Wilson and Synesis Software
  12. * All rights reserved.
  13. *
  14. * Redistribution and use in source and binary forms, with or without
  15. * modification, are permitted provided that the following conditions are met:
  16. *
  17. * - Redistributions of source code must retain the above copyright notice, this
  18. * list of conditions and the following disclaimer.
  19. * - Redistributions in binary form must reproduce the above copyright notice,
  20. * this list of conditions and the following disclaimer in the documentation
  21. * and/or other materials provided with the distribution.
  22. * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
  23. * any contributors may be used to endorse or promote products derived from
  24. * this software without specific prior written permission.
  25. *
  26. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  27. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  28. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  29. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  30. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  31. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  32. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  33. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  34. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  35. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  36. * POSSIBILITY OF SUCH DAMAGE.
  37. *
  38. * ////////////////////////////////////////////////////////////////////// */
  39. /** \file winstl/security/token_information.hpp
  40. *
  41. * \brief [C++ only] Definition of the winstl::token_information class
  42. * (\ref group__library__security "Security" Library).
  43. */
  44. #ifndef WINSTL_INCL_WINSTL_SECURITY_HPP_TOKEN_INFORMATION
  45. #define WINSTL_INCL_WINSTL_SECURITY_HPP_TOKEN_INFORMATION
  46. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  47. # define WINSTL_VER_WINSTL_SECURITY_HPP_TOKEN_INFORMATION_MAJOR 4
  48. # define WINSTL_VER_WINSTL_SECURITY_HPP_TOKEN_INFORMATION_MINOR 1
  49. # define WINSTL_VER_WINSTL_SECURITY_HPP_TOKEN_INFORMATION_REVISION 1
  50. # define WINSTL_VER_WINSTL_SECURITY_HPP_TOKEN_INFORMATION_EDIT 53
  51. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  52. /* /////////////////////////////////////////////////////////////////////////
  53. * Includes
  54. */
  55. #ifndef WINSTL_INCL_WINSTL_H_WINSTL
  56. # include <winstl/winstl.h>
  57. #endif /* !WINSTL_INCL_WINSTL_H_WINSTL */
  58. #ifndef WINSTL_INCL_WINSTL_MEMORY_HPP_PROCESSHEAP_ALLOCATOR
  59. # include <winstl/memory/processheap_allocator.hpp>
  60. #endif /* !WINSTL_INCL_WINSTL_MEMORY_HPP_PROCESSHEAP_ALLOCATOR */
  61. #ifndef STLSOFT_INCL_STLSOFT_ERROR_HPP_EXCEPTIONS
  62. # include <stlsoft/error/exceptions.hpp> // for null_exception_policy
  63. #endif /* !STLSOFT_INCL_STLSOFT_ERROR_HPP_EXCEPTIONS */
  64. #ifndef WINSTL_INCL_WINSTL_ERROR_HPP_LAST_ERROR_SCOPE
  65. # include <winstl/error/last_error_scope.hpp>
  66. #endif /* !WINSTL_INCL_WINSTL_ERROR_HPP_LAST_ERROR_SCOPE */
  67. /* /////////////////////////////////////////////////////////////////////////
  68. * Namespace
  69. */
  70. #ifndef _WINSTL_NO_NAMESPACE
  71. # if defined(_STLSOFT_NO_NAMESPACE) || \
  72. defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  73. /* There is no stlsoft namespace, so must define ::winstl */
  74. namespace winstl
  75. {
  76. # else
  77. /* Define stlsoft::winstl_project */
  78. namespace stlsoft
  79. {
  80. namespace winstl_project
  81. {
  82. # endif /* _STLSOFT_NO_NAMESPACE */
  83. #endif /* !_WINSTL_NO_NAMESPACE */
  84. /* ////////////////////////////////////////////////////////////////////// */
  85. enum
  86. {
  87. TokenRestrictedSids = 1 + TokenStatistics
  88. , TokenSessionId
  89. , TokenGroupsAndPrivileges
  90. , TokenSessionReference
  91. , TokenSandBoxInert
  92. , TokenAuditPolicy
  93. , TokenOrigin
  94. };
  95. /* /////////////////////////////////////////////////////////////////////////
  96. * Classes
  97. */
  98. /** \brief traits type used to determine the data type for a given \c TOKEN_INFORMATION_CLASS
  99. *
  100. * \ingroup group__library__security
  101. *
  102. */
  103. template <TOKEN_INFORMATION_CLASS C>
  104. struct token_information_traits;
  105. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  106. STLSOFT_TEMPLATE_SPECIALISATION
  107. struct token_information_traits<TokenUser>
  108. {
  109. typedef TOKEN_USER data_type;
  110. };
  111. STLSOFT_TEMPLATE_SPECIALISATION
  112. struct token_information_traits<TokenGroups>
  113. {
  114. typedef TOKEN_GROUPS data_type;
  115. };
  116. STLSOFT_TEMPLATE_SPECIALISATION
  117. struct token_information_traits<TokenPrivileges>
  118. {
  119. typedef TOKEN_PRIVILEGES data_type;
  120. };
  121. STLSOFT_TEMPLATE_SPECIALISATION
  122. struct token_information_traits<TokenOwner>
  123. {
  124. typedef TOKEN_OWNER data_type;
  125. };
  126. STLSOFT_TEMPLATE_SPECIALISATION
  127. struct token_information_traits<TokenPrimaryGroup>
  128. {
  129. typedef TOKEN_PRIMARY_GROUP data_type;
  130. };
  131. STLSOFT_TEMPLATE_SPECIALISATION
  132. struct token_information_traits<TokenDefaultDacl>
  133. {
  134. typedef TOKEN_DEFAULT_DACL data_type;
  135. };
  136. STLSOFT_TEMPLATE_SPECIALISATION
  137. struct token_information_traits<TokenSource>
  138. {
  139. typedef TOKEN_SOURCE data_type;
  140. };
  141. STLSOFT_TEMPLATE_SPECIALISATION
  142. struct token_information_traits<TokenType>
  143. {
  144. typedef TOKEN_TYPE data_type;
  145. };
  146. STLSOFT_TEMPLATE_SPECIALISATION
  147. struct token_information_traits<TokenImpersonationLevel>
  148. {
  149. typedef SECURITY_IMPERSONATION_LEVEL data_type;
  150. };
  151. STLSOFT_TEMPLATE_SPECIALISATION
  152. struct token_information_traits<TokenStatistics>
  153. {
  154. typedef TOKEN_STATISTICS data_type;
  155. };
  156. STLSOFT_TEMPLATE_SPECIALISATION
  157. struct token_information_traits<static_cast<TOKEN_INFORMATION_CLASS>(TokenRestrictedSids)>
  158. {
  159. typedef TOKEN_GROUPS data_type;
  160. };
  161. STLSOFT_TEMPLATE_SPECIALISATION
  162. struct token_information_traits<static_cast<TOKEN_INFORMATION_CLASS>(TokenSessionId)>
  163. {
  164. typedef DWORD data_type;
  165. };
  166. #if defined(WINSTL_TOKEN_INFORMATION_TOKEN_GROUPS_AND_PRIVILEGES_SUPPORT) || \
  167. ( !defined(WINSTL_TOKEN_INFORMATION_NO_GUESS) && \
  168. defined(SE_MANAGE_VOLUME_NAME))
  169. STLSOFT_TEMPLATE_SPECIALISATION
  170. struct token_information_traits<static_cast<TOKEN_INFORMATION_CLASS>(TokenGroupsAndPrivileges)>
  171. {
  172. typedef TOKEN_GROUPS_AND_PRIVILEGES data_type;
  173. };
  174. #endif /* TOKEN_GROUPS_AND_PRIVILEGES */
  175. STLSOFT_TEMPLATE_SPECIALISATION
  176. struct token_information_traits<static_cast<TOKEN_INFORMATION_CLASS>(TokenSandBoxInert)>
  177. {
  178. typedef DWORD data_type;
  179. };
  180. #if defined(WINSTL_TOKEN_INFORMATION_TOKEN_ORIGIN_SUPPORT) /* || \
  181. ( !defined(WINSTL_TOKEN_INFORMATION_NO_GUESS) && \
  182. defined(SE_MANAGE_VOLUME_NAME)) */
  183. STLSOFT_TEMPLATE_SPECIALISATION
  184. struct token_information_traits<static_cast<TOKEN_INFORMATION_CLASS>(TokenOrigin)>
  185. {
  186. typedef TOKEN_ORIGIN data_type;
  187. };
  188. #endif /* TOKEN_ORIGIN */
  189. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  190. // token_information
  191. /** \brief Provides typed access to token information.
  192. *
  193. * \ingroup group__library__security
  194. */
  195. template< TOKEN_INFORMATION_CLASS C
  196. #ifdef STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
  197. # ifdef __SYNSOFT_DBS_COMPILER_SUPPORTS_PRAGMA_MESSAGE
  198. # pragma message(_sscomp_fileline_message("Note that we have to have data_type as a parameter, otherwise VC5&6 have a cow"))
  199. # endif /* __SYNSOFT_DBS_COMPILER_SUPPORTS_PRAGMA_MESSAGE */
  200. , ss_typename_param_k X = stlsoft_ns_qual(null_exception_policy)
  201. , ss_typename_param_k D = ss_typename_type_def_k token_information_traits<C>::data_type
  202. , ss_typename_param_k A = processheap_allocator<ss_byte_t>
  203. #else /* ? STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
  204. , ss_typename_param_k X /* = stlsoft_ns_qual(null_exception_policy) */
  205. , ss_typename_param_k D /* = token_information_traits<C>::data_type */
  206. , ss_typename_param_k A /* = processheap_allocator<ss_byte_t> */
  207. #endif /* STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
  208. >
  209. class token_information
  210. {
  211. /// \name Member Types
  212. /// @{
  213. public:
  214. typedef token_information<C, X, D, A> class_type;
  215. typedef token_information_traits<C> traits_type;
  216. typedef X exception_thrower_type;
  217. typedef D data_type;
  218. typedef A allocator_type;
  219. // typedef ss_typename_type_k traits_type::data_type data_type;
  220. /// @}
  221. /// \name Construction
  222. /// @{
  223. public:
  224. /// \brief Constructs an instance from the given access token
  225. ///
  226. ss_explicit_k token_information(HANDLE hToken)
  227. : m_data(0)
  228. {
  229. DWORD cbRequired;
  230. DWORD dwError;
  231. ::GetTokenInformation(hToken, C, NULL, 0, &cbRequired);
  232. dwError = ::GetLastError();
  233. if(ERROR_INSUFFICIENT_BUFFER != dwError)
  234. {
  235. // Report error
  236. exception_thrower_type()(dwError);
  237. }
  238. else
  239. {
  240. data_type *data = reinterpret_cast<data_type*>(allocator_type().allocate(cbRequired));
  241. if(NULL == data)
  242. {
  243. // Report error
  244. exception_thrower_type()(ERROR_NOT_ENOUGH_MEMORY);
  245. // Set the last error, in case the client code is not using exception reporting
  246. ::SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  247. }
  248. else
  249. {
  250. if(!::GetTokenInformation(hToken, C, data, cbRequired, &cbRequired))
  251. {
  252. // Scope the last error, in case the client code is not using exception reporting
  253. last_error_scope scope;
  254. allocator_type().deallocate(reinterpret_cast<ss_byte_t*>(data));
  255. // Report error
  256. exception_thrower_type()(DWORD((scope)));
  257. }
  258. else
  259. {
  260. // Success
  261. m_data = data;
  262. ::SetLastError(ERROR_SUCCESS);
  263. }
  264. }
  265. }
  266. }
  267. ~token_information() stlsoft_throw_0()
  268. {
  269. allocator_type().deallocate(reinterpret_cast<ss_byte_t*>(m_data));
  270. }
  271. /// @}
  272. /// \name Conversion
  273. /// @{
  274. public:
  275. operator data_type *()
  276. {
  277. return m_data;
  278. }
  279. operator data_type const* () const
  280. {
  281. return m_data;
  282. }
  283. data_type *operator ->()
  284. {
  285. return m_data;
  286. }
  287. data_type const* operator ->() const
  288. {
  289. return m_data;
  290. }
  291. /*
  292. operator ws_bool_t () const
  293. {
  294. return 0 != m_data;
  295. }
  296. */
  297. ws_bool_t operator !() const
  298. {
  299. return 0 == m_data;
  300. }
  301. /// @}
  302. /// \name Implementation
  303. /// @{
  304. private:
  305. /// @}
  306. /// \name Members
  307. /// @{
  308. private:
  309. data_type *m_data;
  310. /// @}
  311. /// \name Not to be implemented
  312. /// @{
  313. private:
  314. token_information(token_information const&);
  315. token_information& operator =(token_information const&);
  316. /// @}
  317. };
  318. /* ////////////////////////////////////////////////////////////////////// */
  319. #ifndef _WINSTL_NO_NAMESPACE
  320. # if defined(_STLSOFT_NO_NAMESPACE) || \
  321. defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  322. } // namespace winstl
  323. # else
  324. } // namespace winstl_project
  325. } // namespace stlsoft
  326. # endif /* _STLSOFT_NO_NAMESPACE */
  327. #endif /* !_WINSTL_NO_NAMESPACE */
  328. /* ////////////////////////////////////////////////////////////////////// */
  329. #endif /* WINSTL_INCL_WINSTL_SECURITY_HPP_TOKEN_INFORMATION */
  330. /* ///////////////////////////// end of file //////////////////////////// */