xref: /reactos/dll/win32/authz/resman.c (revision c2c66aff)
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