2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/advapi32/token/token.c
5 * PURPOSE: Token functions
6 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
13 #include <ndk/setypes.h>
15 WINE_DEFAULT_DEBUG_CHANNEL(advapi
);
21 CheckTokenMembership(IN HANDLE ExistingTokenHandle
,
25 PISECURITY_DESCRIPTOR SecurityDescriptor
= NULL
;
26 ACCESS_MASK GrantedAccess
;
29 PRIVILEGE_SET PrivilegeSet
;
30 LUID_AND_ATTRIBUTES Privileges
[4];
32 ULONG PrivBufferSize
= sizeof(PrivBuffer
);
33 GENERIC_MAPPING GenericMapping
=
36 STANDARD_RIGHTS_WRITE
,
37 STANDARD_RIGHTS_EXECUTE
,
43 NTSTATUS Status
, AccessStatus
;
45 /* doesn't return gracefully if IsMember is NULL! */
48 SidLen
= RtlLengthSid(SidToCheck
);
50 if (ExistingTokenHandle
== NULL
)
52 Status
= NtOpenThreadToken(NtCurrentThread(),
57 if (Status
== STATUS_NO_TOKEN
)
59 /* we're not impersonating, open the primary token */
60 Status
= NtOpenProcessToken(NtCurrentProcess(),
61 TOKEN_QUERY
| TOKEN_DUPLICATE
,
63 if (NT_SUCCESS(Status
))
65 HANDLE hNewToken
= FALSE
;
68 /* duplicate the primary token to create an impersonation token */
69 DupRet
= DuplicateTokenEx(hToken
,
70 TOKEN_QUERY
| TOKEN_IMPERSONATE
,
72 SecurityImpersonation
,
80 WARN("Failed to duplicate the primary token!\n");
88 if (!NT_SUCCESS(Status
))
95 hToken
= ExistingTokenHandle
;
98 /* create a security descriptor */
99 SecurityDescriptor
= RtlAllocateHeap(RtlGetProcessHeap(),
101 sizeof(SECURITY_DESCRIPTOR
) +
102 sizeof(ACL
) + SidLen
+
103 sizeof(ACCESS_ALLOWED_ACE
));
104 if (SecurityDescriptor
== NULL
)
106 Status
= STATUS_INSUFFICIENT_RESOURCES
;
110 Status
= RtlCreateSecurityDescriptor(SecurityDescriptor
,
111 SECURITY_DESCRIPTOR_REVISION
);
112 if (!NT_SUCCESS(Status
))
117 /* set the owner and group */
118 Status
= RtlSetOwnerSecurityDescriptor(SecurityDescriptor
,
121 if (!NT_SUCCESS(Status
))
126 Status
= RtlSetGroupSecurityDescriptor(SecurityDescriptor
,
129 if (!NT_SUCCESS(Status
))
134 /* create the DACL */
135 Dacl
= (PACL
)(SecurityDescriptor
+ 1);
136 Status
= RtlCreateAcl(Dacl
,
137 sizeof(ACL
) + SidLen
+ sizeof(ACCESS_ALLOWED_ACE
),
139 if (!NT_SUCCESS(Status
))
144 Status
= RtlAddAccessAllowedAce(Dacl
,
148 if (!NT_SUCCESS(Status
))
153 /* assign the DACL to the security descriptor */
154 Status
= RtlSetDaclSecurityDescriptor(SecurityDescriptor
,
158 if (!NT_SUCCESS(Status
))
163 /* it's time to perform the access check. Just use _some_ desired access right
164 (same as for the ACE) and see if we're getting it granted. This indicates
165 our SID is a member of the token. We however can't use a generic access
166 right as those aren't mapped and return an error (STATUS_GENERIC_NOT_MAPPED). */
167 Status
= NtAccessCheck(SecurityDescriptor
,
171 &PrivBuffer
.PrivilegeSet
,
175 if (NT_SUCCESS(Status
) && NT_SUCCESS(AccessStatus
) && (GrantedAccess
== 0x1))
181 if (hToken
!= NULL
&& hToken
!= ExistingTokenHandle
)
186 if (SecurityDescriptor
!= NULL
)
188 RtlFreeHeap(RtlGetProcessHeap(),
193 if (!NT_SUCCESS(Status
))
195 SetLastError(RtlNtStatusToDosError(Status
));
207 IsTokenRestricted(HANDLE TokenHandle
)
210 PTOKEN_GROUPS lpGroups
;
214 /* determine the required buffer size and allocate enough memory to read the
215 list of restricted SIDs */
216 Status
= NtQueryInformationToken(TokenHandle
,
221 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
223 SetLastError(RtlNtStatusToDosError(Status
));
227 AllocAndReadRestrictedSids
:
228 lpGroups
= (PTOKEN_GROUPS
)HeapAlloc(GetProcessHeap(),
231 if (lpGroups
== NULL
)
233 SetLastError(ERROR_OUTOFMEMORY
);
237 /* actually read the list of the restricted SIDs */
238 Status
= NtQueryInformationToken(TokenHandle
,
243 if (NT_SUCCESS(Status
))
245 Ret
= (lpGroups
->GroupCount
!= 0);
247 else if (Status
== STATUS_BUFFER_TOO_SMALL
)
249 /* looks like the token was modified in the meanwhile, let's just try again */
250 HeapFree(GetProcessHeap(),
254 goto AllocAndReadRestrictedSids
;
258 SetLastError(RtlNtStatusToDosError(Status
));
261 /* free allocated memory */
262 HeapFree(GetProcessHeap(),
274 GetSiteSidFromToken(IN HANDLE TokenHandle
)
276 PTOKEN_GROUPS RestrictedSids
;
280 PSID PSiteSid
= NULL
;
281 SID_IDENTIFIER_AUTHORITY InternetSiteAuthority
= {SECURITY_INTERNETSITE_AUTHORITY
};
283 Status
= NtQueryInformationToken(TokenHandle
,
288 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
290 SetLastError(RtlNtStatusToDosError(Status
));
294 RestrictedSids
= (PTOKEN_GROUPS
)RtlAllocateHeap(RtlGetProcessHeap(),
297 if (RestrictedSids
== NULL
)
299 SetLastError(ERROR_OUTOFMEMORY
);
303 Status
= NtQueryInformationToken(TokenHandle
,
308 if (NT_SUCCESS(Status
))
310 for (i
= 0; i
< RestrictedSids
->GroupCount
; i
++)
312 SID
* RSSid
= RestrictedSids
->Groups
[i
].Sid
;
314 if (RtlCompareMemory(&(RSSid
->IdentifierAuthority
),
315 &InternetSiteAuthority
,
316 sizeof(SID_IDENTIFIER_AUTHORITY
)) ==
317 sizeof(SID_IDENTIFIER_AUTHORITY
))
319 PSiteSid
= RtlAllocateHeap(RtlGetProcessHeap(),
321 RtlLengthSid((RestrictedSids
->
323 if (PSiteSid
== NULL
)
325 SetLastError(ERROR_OUTOFMEMORY
);
329 RtlCopySid(RtlLengthSid(RestrictedSids
->Groups
[i
].Sid
),
331 RestrictedSids
->Groups
[i
].Sid
);
340 SetLastError(RtlNtStatusToDosError(Status
));
343 RtlFreeHeap(RtlGetProcessHeap(), 0, RestrictedSids
);