ReactOS  0.4.12-dev-75-g00dd17e
security.cxx
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Service Host
3  * LICENSE: BSD - See COPYING.ARM in the top level directory
4  * FILE: base/services/svchost/security.cxx
5  * PURPOSE: Initializes the COM Object Security Model and Parameters
6  * PROGRAMMERS: ReactOS Portable Systems Group
7  */
8 
9 /* INCLUDES ******************************************************************/
10 
11 extern "C"
12 {
13 #include "svchost.h"
14 
15 #include <aclapi.h>
16 #include <objidl.h>
17 }
18 
19 /* GLOBALS *******************************************************************/
20 
22 
23 /* FUNCTIONS *****************************************************************/
24 
25 DWORD
26 WINAPI
28  _Out_ PVOID *ppSecurityDescriptor,
29  _Out_ PACL *ppAcl
30  )
31 {
32  HANDLE hToken;
33  DWORD dwGroupLength, dwUserLength, dwError, dwAlignLength;
34  PTOKEN_PRIMARY_GROUP pTokenGroup;
35  PTOKEN_USER pTokenUser;
36  EXPLICIT_ACCESS_W pListOfExplicitEntries;
37  PACL pAcl = NULL;
39 
40  /* Assume failure */
41  *ppSecurityDescriptor = NULL;
42  *ppAcl = NULL;
43 
44  /* Open the token of the current thread */
45  if (OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, 0, &hToken) == FALSE)
46  {
47  /* The thread is not impersonating, use the process token */
49  {
50  /* No token could be queried, fail */
51  return GetLastError();
52  }
53  }
54 
55  /* Get the size of the token's user */
56  if ((GetTokenInformation(hToken, TokenUser, NULL, 0, &dwUserLength) == FALSE) ||
58  {
59  return GetLastError();
60  }
61 
62  /* Get the size of the token's primary group */
63  if ((GetTokenInformation(hToken, TokenPrimaryGroup, NULL, 0, &dwGroupLength) == FALSE) ||
65  {
66  return GetLastError();
67  }
68 
69  /* Allocate an SD large enough to hold the SIDs for the above */
70  dwAlignLength = ALIGN_UP(dwUserLength, ULONG);
72  dwAlignLength +
73  dwGroupLength +
74  sizeof(*pSd));
75  if (pSd == NULL) return ERROR_OUTOFMEMORY;
76 
77  /* Assume success for now */
78  dwError = ERROR_SUCCESS;
79 
80  /* We'll put them right after the SD itself */
81  pTokenUser = (PTOKEN_USER)(pSd + 1);
82  pTokenGroup = (PTOKEN_PRIMARY_GROUP)((ULONG_PTR)pTokenUser + dwAlignLength);
83 
84  /* Now initialize it */
86  {
87  dwError = GetLastError();
88  }
89 
90  /* And do the actual query for the user */
91  if (GetTokenInformation(hToken,
92  TokenUser,
93  pTokenUser,
94  dwUserLength,
95  &dwUserLength) == FALSE)
96  {
97  dwError = GetLastError();
98  }
99 
100  /* And then the actual query for the primary group */
101  if (GetTokenInformation(hToken,
103  pTokenGroup,
104  dwGroupLength,
105  &dwGroupLength) == FALSE)
106  {
107  dwError = GetLastError();
108  }
109 
110  /* Set the user as owner */
111  if (SetSecurityDescriptorOwner(pSd, pTokenUser->User.Sid, FALSE) == FALSE)
112  {
113  dwError = GetLastError();
114  }
115 
116  /* Set the group as primary */
117  if (SetSecurityDescriptorGroup(pSd, pTokenGroup->PrimaryGroup, FALSE) == FALSE)
118  {
119  dwError = GetLastError();
120  }
121 
122  /* Did everything so far work out? */
123  if (dwError == ERROR_SUCCESS)
124  {
125  /* Yes, create an ACL granting the SYSTEM account access */
126  pListOfExplicitEntries.grfAccessMode = SET_ACCESS;
127  pListOfExplicitEntries.Trustee.TrusteeType = TRUSTEE_IS_GROUP;
128  pListOfExplicitEntries.grfAccessPermissions = 1;
129  pListOfExplicitEntries.grfInheritance = 0;
130  pListOfExplicitEntries.Trustee.pMultipleTrustee = 0;
131  pListOfExplicitEntries.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
132  pListOfExplicitEntries.Trustee.TrusteeForm = TRUSTEE_IS_SID;
133  pListOfExplicitEntries.Trustee.ptstrName = (LPWSTR)&NtSid;
134  dwError = SetEntriesInAclW(1, &pListOfExplicitEntries, NULL, &pAcl);
135  if (dwError == ERROR_SUCCESS)
136  {
137  /* Make that ACL the DACL of the SD we just built */
138  if (SetSecurityDescriptorDacl(pSd, 1, pAcl, FALSE) == FALSE)
139  {
140  /* We failed, bail out */
141  LocalFree(pAcl);
142  dwError = GetLastError();
143  }
144  else
145  {
146  /* Now we have the SD and the ACL all ready to go */
147  *ppSecurityDescriptor = pSd;
148  *ppAcl = pAcl;
149  return ERROR_SUCCESS;
150  }
151  }
152  }
153 
154  /* Failure path, we'll free the SD since the caller can't use it */
155  MemFree(pSd);
156  return dwError;
157 }
158 
159 BOOL
160 WINAPI
162  _In_ DWORD dwParam,
163  _In_ DWORD dwAuthnLevel,
164  _In_ DWORD dwImpLevel,
165  _In_ DWORD dwCapabilities
166  )
167 {
168  HRESULT hr;
169  PACL pAcl;
170  PSECURITY_DESCRIPTOR pSecurityDescriptor;
171  IGlobalOptions *pGlobalOptions;
172  ASSERT(dwParam != 0);
173 
174  /* Create a valid SD and ACL based on the current thread's token */
175  if (DwInitializeSdFromThreadToken(&pSecurityDescriptor, &pAcl) == ERROR_SUCCESS)
176  {
177  /* It worked -- initialize COM without DDE support */
179  }
180  else
181  {
182  /* Don't keep going if we don't have an SD */
183  hr = E_FAIL;
184  }
185 
186  /* Did we make it? */
187  if (SUCCEEDED(hr))
188  {
189  /* Indeed, initialize COM security now */
190  DBG_TRACE("Calling CoInitializeSecurity (dwAuthCapabilities = 0x%08x)\n",
191  dwCapabilities);
192  hr = CoInitializeSecurity(pSecurityDescriptor,
193  -1,
194  NULL,
195  NULL,
196  dwAuthnLevel,
197  dwImpLevel,
198  NULL,
199  dwCapabilities,
200  NULL);
201  if (FAILED(hr)) DBG_ERR("CoInitializeSecurity returned hr=0x%08x\n", hr);
202  }
203 
204  /* Free the SD and ACL since we no longer need it */
205  MemFree(pSecurityDescriptor);
206  LocalFree(pAcl);
207 
208  /* Did we initialize COM correctly? */
209  if (SUCCEEDED(hr))
210  {
211  /* Get the COM Global Options Interface */
213  NULL,
214  CLSCTX_INPROC_SERVER,
215  IID_IGlobalOptions,
216  (LPVOID*)&pGlobalOptions);
217  if (SUCCEEDED(hr))
218  {
219  /* Use it to disable COM exception handling */
220  hr = pGlobalOptions->Set(COMGLB_EXCEPTION_HANDLING,
222  pGlobalOptions->Release();
223  ASSERT(SUCCEEDED(hr));
224  }
225  }
226 
227  /* Return whether all COM calls were successful or not */
228  return SUCCEEDED(hr);
229 }
DWORD WINAPI SetEntriesInAclW(ULONG cCountOfExplicitEntries, PEXPLICIT_ACCESS_W pListOfExplicitEntries, PACL OldAcl, PACL *NewAcl)
Definition: ac.c:199
#define SECURITY_LOCAL_SYSTEM_RID
Definition: setypes.h:546
TRUSTEE_FORM TrusteeForm
Definition: accctrl.h:215
BOOL MemFree(IN PVOID lpMem)
Definition: utils.c:26
#define ERROR_SUCCESS
Definition: deptool.c:10
#define ALIGN_UP(size, type)
Definition: umtypes.h:91
#define DBG_ERR(fmt,...)
Definition: svchost.h:35
struct _TOKEN_PRIMARY_GROUP * PTOKEN_PRIMARY_GROUP
PVOID MemAlloc(IN DWORD dwFlags, IN DWORD dwBytes)
Definition: utils.c:33
BOOL WINAPI InitializeSecurityDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD dwRevision)
Definition: security.c:804
#define SID_REVISION
Definition: setypes.h:453
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
TRUSTEE_TYPE TrusteeType
Definition: accctrl.h:216
HRESULT WINAPI CoInitializeSecurity(PSECURITY_DESCRIPTOR pSecDesc, LONG cAuthSvc, SOLE_AUTHENTICATION_SERVICE *asAuthSvc, void *pReserved1, DWORD dwAuthnLevel, DWORD dwImpLevel, void *pReserved2, DWORD dwCapabilities, void *pReserved3)
Definition: compobj.c:4034
#define E_FAIL
Definition: ddrawi.h:102
SID NtSid
Definition: security.cxx:21
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
const CLSID CLSID_GlobalOptions
HANDLE WINAPI GetCurrentThread(VOID)
Definition: proc.c:1178
BOOL WINAPI InitializeSecurity(_In_ DWORD dwParam, _In_ DWORD dwAuthnLevel, _In_ DWORD dwImpLevel, _In_ DWORD dwCapabilities)
Definition: security.cxx:161
smooth NULL
Definition: ftsmooth.c:416
#define _Out_
Definition: no_sal2.h:323
#define SECURITY_NT_AUTHORITY
Definition: setypes.h:526
unsigned int BOOL
Definition: ntddk_ex.h:94
#define TOKEN_QUERY
Definition: setypes.h:874
LONG HRESULT
Definition: typedefs.h:77
HANDLE WINAPI GetCurrentProcess(VOID)
Definition: proc.c:1168
DWORD grfInheritance
Definition: accctrl.h:342
ACCESS_MODE grfAccessMode
Definition: accctrl.h:341
struct _TRUSTEE_W * pMultipleTrustee
Definition: accctrl.h:213
nsrefcnt Release()
TRUSTEE_W Trustee
Definition: accctrl.h:343
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD WINAPI DwInitializeSdFromThreadToken(_Out_ PVOID *ppSecurityDescriptor, _Out_ PACL *ppAcl)
Definition: security.cxx:27
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define DBG_TRACE(fmt,...)
Definition: svchost.h:36
MULTIPLE_TRUSTEE_OPERATION MultipleTrusteeOperation
Definition: accctrl.h:214
LPWSTR ptstrName
Definition: accctrl.h:217
#define WINAPI
Definition: msvc.h:20
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3237
#define _In_
Definition: no_sal2.h:204
BOOL WINAPI OpenThreadToken(HANDLE ThreadHandle, DWORD DesiredAccess, BOOL OpenAsSelf, HANDLE *TokenHandle)
Definition: security.c:334
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1577
DWORD grfAccessPermissions
Definition: accctrl.h:340
HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
Definition: compobj.c:1938
BOOL WINAPI SetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR pSecurityDescriptor, BOOL bDaclPresent, PACL pDacl, BOOL bDaclDefaulted)
Definition: sec.c:262
BOOL WINAPI OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle)
Definition: security.c:292
unsigned int ULONG
Definition: retypes.h:1
BOOL WINAPI GetTokenInformation(HANDLE TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, LPVOID TokenInformation, DWORD TokenInformationLength, PDWORD ReturnLength)
Definition: security.c:409
struct _TOKEN_USER * PTOKEN_USER
SID_AND_ATTRIBUTES User
Definition: setypes.h:956
BOOL WINAPI SetSecurityDescriptorGroup(PSECURITY_DESCRIPTOR pSecurityDescriptor, PSID pGroup, BOOL bGroupDefaulted)
Definition: sec.c:288
WCHAR * LPWSTR
Definition: xmlstorage.h:184
BOOL WINAPI SetSecurityDescriptorOwner(PSECURITY_DESCRIPTOR pSecurityDescriptor, PSID pOwner, BOOL bOwnerDefaulted)
Definition: sec.c:312
#define SUCCEEDED(hr)
Definition: intsafe.h:57
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
struct _SECURITY_DESCRIPTOR * PISECURITY_DESCRIPTOR
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10