1 /*
2 * ReactOS Authorization Framework
3 * Copyright (C) 2005 - 2006 ReactOS Team
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19 /*
20 * PROJECT: ReactOS Authorization Framework
21 * FILE: lib/authz/resman.c
22 * PURPOSE: Authorization Framework
23 * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com>
24 *
25 * UPDATE HISTORY:
26 * 10/07/2005 Created
27 */
28
29 #include "precomp.h"
30
31 #define NDEBUG
32 #include <debug.h>
33
34 static BOOL
AuthzpQueryToken(IN OUT PAUTHZ_RESMAN ResMan,IN HANDLE hToken)35 AuthzpQueryToken(IN OUT PAUTHZ_RESMAN ResMan,
36 IN HANDLE hToken)
37 {
38 TOKEN_USER User;
39 TOKEN_STATISTICS Statistics;
40 DWORD BufLen;
41 PSID UserSid = NULL;
42 BOOL Ret = FALSE;
43
44 /* query information about the user */
45 BufLen = sizeof(User);
46 Ret = GetTokenInformation(hToken,
47 TokenUser,
48 &User,
49 BufLen,
50 &BufLen);
51 if (Ret)
52 {
53 BufLen = GetLengthSid(User.User.Sid);
54 if (BufLen != 0)
55 {
56 UserSid = (PSID)LocalAlloc(LMEM_FIXED,
57 BufLen);
58 if (UserSid != NULL)
59 {
60 CopyMemory(UserSid,
61 User.User.Sid,
62 BufLen);
63 }
64 else
65 Ret = FALSE;
66 }
67 else
68 Ret = FALSE;
69 }
70
71 if (Ret)
72 {
73 /* query general information */
74 BufLen = sizeof(Statistics);
75 Ret = GetTokenInformation(hToken,
76 TokenUser,
77 &Statistics,
78 BufLen,
79 &BufLen);
80 }
81
82 if (Ret)
83 {
84 ResMan->UserSid = UserSid;
85 ResMan->AuthenticationId = Statistics.AuthenticationId;
86 Ret = TRUE;
87 }
88 else
89 {
90 if (UserSid != NULL)
91 {
92 LocalFree((HLOCAL)UserSid);
93 }
94 }
95
96 return Ret;
97 }
98
99 static BOOL
AuthzpInitUnderImpersonation(IN OUT PAUTHZ_RESMAN ResMan)100 AuthzpInitUnderImpersonation(IN OUT PAUTHZ_RESMAN ResMan)
101 {
102 HANDLE hToken;
103 BOOL Ret;
104
105 Ret = OpenThreadToken(GetCurrentThread(),
106 TOKEN_QUERY,
107 TRUE,
108 &hToken);
109 if (Ret)
110 {
111 Ret = AuthzpQueryToken(ResMan,
112 hToken);
113 CloseHandle(hToken);
114 }
115
116 return Ret;
117 }
118
119 static BOOL
AuthzpInitSelf(IN OUT PAUTHZ_RESMAN ResMan)120 AuthzpInitSelf(IN OUT PAUTHZ_RESMAN ResMan)
121 {
122 HANDLE hToken;
123 BOOL Ret;
124
125 Ret = OpenProcessToken(GetCurrentProcess(),
126 TOKEN_QUERY,
127 &hToken);
128 if (Ret)
129 {
130 Ret = AuthzpQueryToken(ResMan,
131 hToken);
132 CloseHandle(hToken);
133 }
134
135 return Ret;
136 }
137
138
139 /*
140 * @unimplemented
141 */
142 AUTHZAPI
143 BOOL
144 WINAPI
AuthzInitializeResourceManager(IN DWORD flags,IN PFN_AUTHZ_DYNAMIC_ACCESS_CHECK pfnAccessCheck OPTIONAL,IN PFN_AUTHZ_COMPUTE_DYNAMIC_GROUPS pfnComputeDynamicGroups OPTIONAL,IN PFN_AUTHZ_FREE_DYNAMIC_GROUPS pfnFreeDynamicGroups OPTIONAL,IN PCWSTR ResourceManagerName OPTIONAL,IN PAUTHZ_RESOURCE_MANAGER_HANDLE pAuthzResourceManager)145 AuthzInitializeResourceManager(IN DWORD flags,
146 IN PFN_AUTHZ_DYNAMIC_ACCESS_CHECK pfnAccessCheck OPTIONAL,
147 IN PFN_AUTHZ_COMPUTE_DYNAMIC_GROUPS pfnComputeDynamicGroups OPTIONAL,
148 IN PFN_AUTHZ_FREE_DYNAMIC_GROUPS pfnFreeDynamicGroups OPTIONAL,
149 IN PCWSTR ResourceManagerName OPTIONAL,
150 IN PAUTHZ_RESOURCE_MANAGER_HANDLE pAuthzResourceManager)
151 {
152 BOOL Ret = FALSE;
153
154 if (pAuthzResourceManager != NULL &&
155 !(flags & ~(AUTHZ_RM_FLAG_NO_AUDIT | AUTHZ_RM_FLAG_INITIALIZE_UNDER_IMPERSONATION)))
156 {
157 PAUTHZ_RESMAN ResMan;
158 SIZE_T RequiredSize = sizeof(AUTHZ_RESMAN);
159
160 if (ResourceManagerName != NULL)
161 {
162 RequiredSize += wcslen(ResourceManagerName) * sizeof(WCHAR);
163 }
164
165 ResMan = (PAUTHZ_RESMAN)LocalAlloc(LMEM_FIXED,
166 RequiredSize);
167 if (ResMan != NULL)
168 {
169 /* initialize the resource manager structure */
170 #if DBG
171 ResMan->Tag = RESMAN_TAG;
172 #endif
173
174 ResMan->flags = flags;
175 ResMan->UserSid = NULL;
176
177 if (ResourceManagerName != NULL)
178 {
179 wcscpy(ResMan->ResourceManagerName,
180 ResourceManagerName);
181 }
182 else
183 ResMan->ResourceManagerName[0] = UNICODE_NULL;
184
185 ResMan->pfnAccessCheck = pfnAccessCheck;
186 ResMan->pfnComputeDynamicGroups = pfnComputeDynamicGroups;
187 ResMan->pfnFreeDynamicGroups = pfnFreeDynamicGroups;
188
189 if (!(flags & AUTHZ_RM_FLAG_NO_AUDIT))
190 {
191 /* FIXME - initialize auditing */
192 DPRINT1("Auditing not implemented!\n");
193 }
194
195 if (flags & AUTHZ_RM_FLAG_INITIALIZE_UNDER_IMPERSONATION)
196 {
197 Ret = AuthzpInitUnderImpersonation(ResMan);
198 }
199 else
200 {
201 Ret = AuthzpInitSelf(ResMan);
202 }
203
204 if (Ret)
205 {
206 /* finally return the handle */
207 *pAuthzResourceManager = (AUTHZ_RESOURCE_MANAGER_HANDLE)ResMan;
208 }
209 else
210 {
211 DPRINT1("Querying the token failed!\n");
212 LocalFree((HLOCAL)ResMan);
213 }
214 }
215 }
216 else
217 SetLastError(ERROR_INVALID_PARAMETER);
218
219 return Ret;
220 }
221
222
223 /*
224 * @unimplemented
225 */
226 AUTHZAPI
227 BOOL
228 WINAPI
AuthzFreeResourceManager(IN AUTHZ_RESOURCE_MANAGER_HANDLE AuthzResourceManager)229 AuthzFreeResourceManager(IN AUTHZ_RESOURCE_MANAGER_HANDLE AuthzResourceManager)
230 {
231 BOOL Ret = FALSE;
232
233 if (AuthzResourceManager != NULL)
234 {
235 PAUTHZ_RESMAN ResMan = (PAUTHZ_RESMAN)AuthzResourceManager;
236
237 VALIDATE_RESMAN_HANDLE(AuthzResourceManager);
238
239 if (!(ResMan->flags & AUTHZ_RM_FLAG_NO_AUDIT))
240 {
241 /* FIXME - cleanup auditing */
242 }
243
244 if (ResMan->UserSid != NULL)
245 {
246 LocalFree((HLOCAL)ResMan->UserSid);
247 }
248
249 LocalFree((HLOCAL)AuthzResourceManager);
250 Ret = TRUE;
251 }
252 else
253 SetLastError(ERROR_INVALID_PARAMETER);
254
255 return Ret;
256 }
257
258