Commit dd77ff75 authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Move the token functions to the Unix library.

parent a47f4daf
......@@ -52,6 +52,7 @@ C_SRCS = \
unix/loader.c \
unix/process.c \
unix/registry.c \
unix/security.c \
unix/serial.c \
unix/server.c \
unix/signal_arm.c \
......
......@@ -32,14 +32,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
LPCSTR debugstr_ObjectAttributes(const OBJECT_ATTRIBUTES *oa)
{
if (!oa) return "<null>";
return wine_dbg_sprintf( "{name=%s, attr=0x%08x, hRoot=%p, sd=%p}",
debugstr_us(oa->ObjectName), oa->Attributes,
oa->RootDirectory, oa->SecurityDescriptor );
}
LPCSTR debugstr_us( const UNICODE_STRING *us )
{
if (!us) return "<null>";
......@@ -567,18 +559,6 @@ ULONG WINAPIV EtwTraceMessage( TRACEHANDLE handle, ULONG flags, LPGUID guid, /*U
return ret;
}
NTSTATUS WINAPI NtCreateLowBoxToken(HANDLE *token_handle, HANDLE existing_token_handle, ACCESS_MASK desired_access,
OBJECT_ATTRIBUTES *object_attributes, SID *package_sid, ULONG capability_count,
SID_AND_ATTRIBUTES *capabilities, ULONG handle_count, HANDLE *handle)
{
FIXME("(%p, %p, %x, %p, %p, %u, %p, %u, %p): stub\n", token_handle, existing_token_handle, desired_access,
object_attributes, package_sid, capability_count, capabilities, handle_count, handle);
/* We need to return a NULL handle since later it will be passed to CloseHandle and that must not fail */
*token_handle = NULL;
return STATUS_SUCCESS;
}
/*********************************************************************
* ApiSetQueryApiSetPresence (NTDLL.@)
*/
......
......@@ -42,637 +42,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
* Token
*/
/******************************************************************************
* NtDuplicateToken [NTDLL.@]
* ZwDuplicateToken [NTDLL.@]
*/
NTSTATUS WINAPI NtDuplicateToken(
IN HANDLE ExistingToken,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
IN TOKEN_TYPE TokenType,
OUT PHANDLE NewToken)
{
NTSTATUS status;
data_size_t len;
struct object_attributes *objattr;
TRACE("(%p,0x%08x,%s,0x%08x,0x%08x,%p)\n",
ExistingToken, DesiredAccess, debugstr_ObjectAttributes(ObjectAttributes),
ImpersonationLevel, TokenType, NewToken);
if ((status = alloc_object_attributes( ObjectAttributes, &objattr, &len ))) return status;
if (ObjectAttributes && ObjectAttributes->SecurityQualityOfService)
{
SECURITY_QUALITY_OF_SERVICE *SecurityQOS = ObjectAttributes->SecurityQualityOfService;
TRACE("ObjectAttributes->SecurityQualityOfService = {%d, %d, %d, %s}\n",
SecurityQOS->Length, SecurityQOS->ImpersonationLevel,
SecurityQOS->ContextTrackingMode,
SecurityQOS->EffectiveOnly ? "TRUE" : "FALSE");
ImpersonationLevel = SecurityQOS->ImpersonationLevel;
}
SERVER_START_REQ( duplicate_token )
{
req->handle = wine_server_obj_handle( ExistingToken );
req->access = DesiredAccess;
req->primary = (TokenType == TokenPrimary);
req->impersonation_level = ImpersonationLevel;
wine_server_add_data( req, objattr, len );
status = wine_server_call( req );
if (!status) *NewToken = wine_server_ptr_handle( reply->new_handle );
}
SERVER_END_REQ;
RtlFreeHeap( GetProcessHeap(), 0, objattr );
return status;
}
/******************************************************************************
* NtOpenProcessToken [NTDLL.@]
* ZwOpenProcessToken [NTDLL.@]
*/
NTSTATUS WINAPI NtOpenProcessToken(
HANDLE ProcessHandle,
DWORD DesiredAccess,
HANDLE *TokenHandle)
{
return NtOpenProcessTokenEx( ProcessHandle, DesiredAccess, 0, TokenHandle );
}
/******************************************************************************
* NtOpenProcessTokenEx [NTDLL.@]
* ZwOpenProcessTokenEx [NTDLL.@]
*/
NTSTATUS WINAPI NtOpenProcessTokenEx( HANDLE process, DWORD access, DWORD attributes,
HANDLE *handle )
{
NTSTATUS ret;
TRACE("(%p,0x%08x,0x%08x,%p)\n", process, access, attributes, handle);
SERVER_START_REQ( open_token )
{
req->handle = wine_server_obj_handle( process );
req->access = access;
req->attributes = attributes;
req->flags = 0;
ret = wine_server_call( req );
if (!ret) *handle = wine_server_ptr_handle( reply->token );
}
SERVER_END_REQ;
return ret;
}
/******************************************************************************
* NtOpenThreadToken [NTDLL.@]
* ZwOpenThreadToken [NTDLL.@]
*/
NTSTATUS WINAPI NtOpenThreadToken(
HANDLE ThreadHandle,
DWORD DesiredAccess,
BOOLEAN OpenAsSelf,
HANDLE *TokenHandle)
{
return NtOpenThreadTokenEx( ThreadHandle, DesiredAccess, OpenAsSelf, 0, TokenHandle );
}
/******************************************************************************
* NtOpenThreadTokenEx [NTDLL.@]
* ZwOpenThreadTokenEx [NTDLL.@]
*/
NTSTATUS WINAPI NtOpenThreadTokenEx( HANDLE thread, DWORD access, BOOLEAN as_self, DWORD attributes,
HANDLE *handle )
{
NTSTATUS ret;
TRACE("(%p,0x%08x,%u,0x%08x,%p)\n", thread, access, as_self, attributes, handle );
SERVER_START_REQ( open_token )
{
req->handle = wine_server_obj_handle( thread );
req->access = access;
req->attributes = attributes;
req->flags = OPEN_TOKEN_THREAD;
if (as_self) req->flags |= OPEN_TOKEN_AS_SELF;
ret = wine_server_call( req );
if (!ret) *handle = wine_server_ptr_handle( reply->token );
}
SERVER_END_REQ;
return ret;
}
/******************************************************************************
* NtAdjustPrivilegesToken [NTDLL.@]
* ZwAdjustPrivilegesToken [NTDLL.@]
*
* FIXME: parameters unsafe
*/
NTSTATUS WINAPI NtAdjustPrivilegesToken(
IN HANDLE TokenHandle,
IN BOOLEAN DisableAllPrivileges,
IN PTOKEN_PRIVILEGES NewState,
IN DWORD BufferLength,
OUT PTOKEN_PRIVILEGES PreviousState,
OUT PDWORD ReturnLength)
{
NTSTATUS ret;
TRACE("(%p,0x%08x,%p,0x%08x,%p,%p)\n",
TokenHandle, DisableAllPrivileges, NewState, BufferLength, PreviousState, ReturnLength);
SERVER_START_REQ( adjust_token_privileges )
{
req->handle = wine_server_obj_handle( TokenHandle );
req->disable_all = DisableAllPrivileges;
req->get_modified_state = (PreviousState != NULL);
if (!DisableAllPrivileges)
{
wine_server_add_data( req, NewState->Privileges,
NewState->PrivilegeCount * sizeof(NewState->Privileges[0]) );
}
if (PreviousState && BufferLength >= FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ))
wine_server_set_reply( req, PreviousState->Privileges,
BufferLength - FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ) );
ret = wine_server_call( req );
if (PreviousState)
{
if (ReturnLength) *ReturnLength = reply->len + FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges );
PreviousState->PrivilegeCount = reply->len / sizeof(LUID_AND_ATTRIBUTES);
}
}
SERVER_END_REQ;
return ret;
}
/******************************************************************************
* NtQueryInformationToken [NTDLL.@]
* ZwQueryInformationToken [NTDLL.@]
*
* NOTES
* Buffer for TokenUser:
* 0x00 TOKEN_USER the PSID field points to the SID
* 0x08 SID
*
*/
NTSTATUS WINAPI NtQueryInformationToken(
HANDLE token,
TOKEN_INFORMATION_CLASS tokeninfoclass,
PVOID tokeninfo,
ULONG tokeninfolength,
PULONG retlen )
{
static const ULONG info_len [] =
{
0,
0, /* TokenUser */
0, /* TokenGroups */
0, /* TokenPrivileges */
0, /* TokenOwner */
0, /* TokenPrimaryGroup */
0, /* TokenDefaultDacl */
sizeof(TOKEN_SOURCE), /* TokenSource */
sizeof(TOKEN_TYPE), /* TokenType */
sizeof(SECURITY_IMPERSONATION_LEVEL), /* TokenImpersonationLevel */
sizeof(TOKEN_STATISTICS), /* TokenStatistics */
0, /* TokenRestrictedSids */
sizeof(DWORD), /* TokenSessionId */
0, /* TokenGroupsAndPrivileges */
0, /* TokenSessionReference */
0, /* TokenSandBoxInert */
0, /* TokenAuditPolicy */
0, /* TokenOrigin */
sizeof(TOKEN_ELEVATION_TYPE), /* TokenElevationType */
0, /* TokenLinkedToken */
sizeof(TOKEN_ELEVATION), /* TokenElevation */
0, /* TokenHasRestrictions */
0, /* TokenAccessInformation */
0, /* TokenVirtualizationAllowed */
sizeof(DWORD), /* TokenVirtualizationEnabled */
sizeof(TOKEN_MANDATORY_LABEL) + sizeof(SID), /* TokenIntegrityLevel [sizeof(SID) includes one SubAuthority] */
0, /* TokenUIAccess */
0, /* TokenMandatoryPolicy */
0, /* TokenLogonSid */
sizeof(DWORD), /* TokenIsAppContainer */
0, /* TokenCapabilities */
sizeof(TOKEN_APPCONTAINER_INFORMATION) + sizeof(SID), /* TokenAppContainerSid */
0, /* TokenAppContainerNumber */
0, /* TokenUserClaimAttributes*/
0, /* TokenDeviceClaimAttributes */
0, /* TokenRestrictedUserClaimAttributes */
0, /* TokenRestrictedDeviceClaimAttributes */
0, /* TokenDeviceGroups */
0, /* TokenRestrictedDeviceGroups */
0, /* TokenSecurityAttributes */
0, /* TokenIsRestricted */
0 /* TokenProcessTrustLevel */
};
ULONG len = 0;
NTSTATUS status = STATUS_SUCCESS;
TRACE("(%p,%d,%p,%d,%p)\n",
token,tokeninfoclass,tokeninfo,tokeninfolength,retlen);
if (tokeninfoclass < MaxTokenInfoClass)
len = info_len[tokeninfoclass];
if (retlen) *retlen = len;
if (tokeninfolength < len)
return STATUS_BUFFER_TOO_SMALL;
switch (tokeninfoclass)
{
case TokenUser:
SERVER_START_REQ( get_token_sid )
{
TOKEN_USER * tuser = tokeninfo;
PSID sid = tuser + 1;
DWORD sid_len = tokeninfolength < sizeof(TOKEN_USER) ? 0 : tokeninfolength - sizeof(TOKEN_USER);
req->handle = wine_server_obj_handle( token );
req->which_sid = tokeninfoclass;
wine_server_set_reply( req, sid, sid_len );
status = wine_server_call( req );
if (retlen) *retlen = reply->sid_len + sizeof(TOKEN_USER);
if (status == STATUS_SUCCESS)
{
tuser->User.Sid = sid;
tuser->User.Attributes = 0;
}
}
SERVER_END_REQ;
break;
case TokenGroups:
{
void *buffer;
/* reply buffer is always shorter than output one */
buffer = tokeninfolength ? RtlAllocateHeap(GetProcessHeap(), 0, tokeninfolength) : NULL;
SERVER_START_REQ( get_token_groups )
{
TOKEN_GROUPS *groups = tokeninfo;
req->handle = wine_server_obj_handle( token );
wine_server_set_reply( req, buffer, tokeninfolength );
status = wine_server_call( req );
if (status == STATUS_BUFFER_TOO_SMALL)
{
if (retlen) *retlen = reply->user_len;
}
else if (status == STATUS_SUCCESS)
{
struct token_groups *tg = buffer;
unsigned int *attr = (unsigned int *)(tg + 1);
ULONG i;
const int non_sid_portion = (sizeof(struct token_groups) + tg->count * sizeof(unsigned int));
SID *sids = (SID *)((char *)tokeninfo + FIELD_OFFSET( TOKEN_GROUPS, Groups[tg->count] ));
if (retlen) *retlen = reply->user_len;
groups->GroupCount = tg->count;
memcpy( sids, (char *)buffer + non_sid_portion,
reply->user_len - FIELD_OFFSET( TOKEN_GROUPS, Groups[tg->count] ));
for (i = 0; i < tg->count; i++)
{
groups->Groups[i].Attributes = attr[i];
groups->Groups[i].Sid = sids;
sids = (SID *)((char *)sids + RtlLengthSid(sids));
}
}
else if (retlen) *retlen = 0;
}
SERVER_END_REQ;
RtlFreeHeap(GetProcessHeap(), 0, buffer);
break;
}
case TokenPrimaryGroup:
SERVER_START_REQ( get_token_sid )
{
TOKEN_PRIMARY_GROUP *tgroup = tokeninfo;
PSID sid = tgroup + 1;
DWORD sid_len = tokeninfolength < sizeof(TOKEN_PRIMARY_GROUP) ? 0 : tokeninfolength - sizeof(TOKEN_PRIMARY_GROUP);
req->handle = wine_server_obj_handle( token );
req->which_sid = tokeninfoclass;
wine_server_set_reply( req, sid, sid_len );
status = wine_server_call( req );
if (retlen) *retlen = reply->sid_len + sizeof(TOKEN_PRIMARY_GROUP);
if (status == STATUS_SUCCESS)
tgroup->PrimaryGroup = sid;
}
SERVER_END_REQ;
break;
case TokenPrivileges:
SERVER_START_REQ( get_token_privileges )
{
TOKEN_PRIVILEGES *tpriv = tokeninfo;
req->handle = wine_server_obj_handle( token );
if (tpriv && tokeninfolength > FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ))
wine_server_set_reply( req, tpriv->Privileges, tokeninfolength - FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ) );
status = wine_server_call( req );
if (retlen) *retlen = FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ) + reply->len;
if (tpriv) tpriv->PrivilegeCount = reply->len / sizeof(LUID_AND_ATTRIBUTES);
}
SERVER_END_REQ;
break;
case TokenOwner:
SERVER_START_REQ( get_token_sid )
{
TOKEN_OWNER *towner = tokeninfo;
PSID sid = towner + 1;
DWORD sid_len = tokeninfolength < sizeof(TOKEN_OWNER) ? 0 : tokeninfolength - sizeof(TOKEN_OWNER);
req->handle = wine_server_obj_handle( token );
req->which_sid = tokeninfoclass;
wine_server_set_reply( req, sid, sid_len );
status = wine_server_call( req );
if (retlen) *retlen = reply->sid_len + sizeof(TOKEN_OWNER);
if (status == STATUS_SUCCESS)
towner->Owner = sid;
}
SERVER_END_REQ;
break;
case TokenImpersonationLevel:
SERVER_START_REQ( get_token_impersonation_level )
{
SECURITY_IMPERSONATION_LEVEL *impersonation_level = tokeninfo;
req->handle = wine_server_obj_handle( token );
status = wine_server_call( req );
if (status == STATUS_SUCCESS)
*impersonation_level = reply->impersonation_level;
}
SERVER_END_REQ;
break;
case TokenStatistics:
SERVER_START_REQ( get_token_statistics )
{
TOKEN_STATISTICS *statistics = tokeninfo;
req->handle = wine_server_obj_handle( token );
status = wine_server_call( req );
if (status == STATUS_SUCCESS)
{
statistics->TokenId.LowPart = reply->token_id.low_part;
statistics->TokenId.HighPart = reply->token_id.high_part;
statistics->AuthenticationId.LowPart = 0; /* FIXME */
statistics->AuthenticationId.HighPart = 0; /* FIXME */
statistics->ExpirationTime.u.HighPart = 0x7fffffff;
statistics->ExpirationTime.u.LowPart = 0xffffffff;
statistics->TokenType = reply->primary ? TokenPrimary : TokenImpersonation;
statistics->ImpersonationLevel = reply->impersonation_level;
/* kernel information not relevant to us */
statistics->DynamicCharged = 0;
statistics->DynamicAvailable = 0;
statistics->GroupCount = reply->group_count;
statistics->PrivilegeCount = reply->privilege_count;
statistics->ModifiedId.LowPart = reply->modified_id.low_part;
statistics->ModifiedId.HighPart = reply->modified_id.high_part;
}
}
SERVER_END_REQ;
break;
case TokenType:
SERVER_START_REQ( get_token_statistics )
{
TOKEN_TYPE *token_type = tokeninfo;
req->handle = wine_server_obj_handle( token );
status = wine_server_call( req );
if (status == STATUS_SUCCESS)
*token_type = reply->primary ? TokenPrimary : TokenImpersonation;
}
SERVER_END_REQ;
break;
case TokenDefaultDacl:
SERVER_START_REQ( get_token_default_dacl )
{
TOKEN_DEFAULT_DACL *default_dacl = tokeninfo;
ACL *acl = (ACL *)(default_dacl + 1);
DWORD acl_len;
if (tokeninfolength < sizeof(TOKEN_DEFAULT_DACL)) acl_len = 0;
else acl_len = tokeninfolength - sizeof(TOKEN_DEFAULT_DACL);
req->handle = wine_server_obj_handle( token );
wine_server_set_reply( req, acl, acl_len );
status = wine_server_call( req );
if (retlen) *retlen = reply->acl_len + sizeof(TOKEN_DEFAULT_DACL);
if (status == STATUS_SUCCESS)
{
if (reply->acl_len)
default_dacl->DefaultDacl = acl;
else
default_dacl->DefaultDacl = NULL;
}
}
SERVER_END_REQ;
break;
case TokenElevationType:
{
TOKEN_ELEVATION_TYPE *elevation_type = tokeninfo;
FIXME("QueryInformationToken( ..., TokenElevationType, ...) semi-stub\n");
*elevation_type = TokenElevationTypeFull;
}
break;
case TokenElevation:
{
TOKEN_ELEVATION *elevation = tokeninfo;
FIXME("QueryInformationToken( ..., TokenElevation, ...) semi-stub\n");
elevation->TokenIsElevated = TRUE;
}
break;
case TokenSessionId:
{
*((DWORD*)tokeninfo) = 0;
FIXME("QueryInformationToken( ..., TokenSessionId, ...) semi-stub\n");
}
break;
case TokenVirtualizationEnabled:
{
*(DWORD *)tokeninfo = 0;
TRACE("QueryInformationToken( ..., TokenVirtualizationEnabled, ...) semi-stub\n");
}
break;
case TokenIntegrityLevel:
{
/* report always "S-1-16-12288" (high mandatory level) for now */
static const SID high_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
{SECURITY_MANDATORY_HIGH_RID}};
TOKEN_MANDATORY_LABEL *tml = tokeninfo;
PSID psid = tml + 1;
tml->Label.Sid = psid;
tml->Label.Attributes = SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED;
memcpy(psid, &high_level, sizeof(SID));
}
break;
case TokenAppContainerSid:
{
TOKEN_APPCONTAINER_INFORMATION *container = tokeninfo;
FIXME("QueryInformationToken( ..., TokenAppContainerSid, ...) semi-stub\n");
container->TokenAppContainer = NULL;
}
break;
case TokenIsAppContainer:
{
TRACE("TokenIsAppContainer semi-stub\n");
*(DWORD*)tokeninfo = 0;
break;
}
case TokenLogonSid:
SERVER_START_REQ( get_token_sid )
{
TOKEN_GROUPS * groups = tokeninfo;
PSID sid = groups + 1;
DWORD sid_len = tokeninfolength < sizeof(TOKEN_GROUPS) ? 0 : tokeninfolength - sizeof(TOKEN_GROUPS);
req->handle = wine_server_obj_handle( token );
req->which_sid = tokeninfoclass;
wine_server_set_reply( req, sid, sid_len );
status = wine_server_call( req );
if (retlen) *retlen = reply->sid_len + sizeof(TOKEN_GROUPS);
if (status == STATUS_SUCCESS)
{
groups->GroupCount = 1;
groups->Groups[0].Sid = sid;
groups->Groups[0].Attributes = 0;
}
}
SERVER_END_REQ;
break;
default:
{
ERR("Unhandled Token Information class %d!\n", tokeninfoclass);
return STATUS_NOT_IMPLEMENTED;
}
}
return status;
}
/******************************************************************************
* NtSetInformationToken [NTDLL.@]
* ZwSetInformationToken [NTDLL.@]
*/
NTSTATUS WINAPI NtSetInformationToken(
HANDLE TokenHandle,
TOKEN_INFORMATION_CLASS TokenInformationClass,
PVOID TokenInformation,
ULONG TokenInformationLength)
{
NTSTATUS ret = STATUS_NOT_IMPLEMENTED;
TRACE("%p %d %p %u\n", TokenHandle, TokenInformationClass,
TokenInformation, TokenInformationLength);
switch (TokenInformationClass)
{
case TokenDefaultDacl:
if (TokenInformationLength < sizeof(TOKEN_DEFAULT_DACL))
{
ret = STATUS_INFO_LENGTH_MISMATCH;
break;
}
if (!TokenInformation)
{
ret = STATUS_ACCESS_VIOLATION;
break;
}
SERVER_START_REQ( set_token_default_dacl )
{
ACL *acl = ((TOKEN_DEFAULT_DACL *)TokenInformation)->DefaultDacl;
WORD size;
if (acl) size = acl->AclSize;
else size = 0;
req->handle = wine_server_obj_handle( TokenHandle );
wine_server_add_data( req, acl, size );
ret = wine_server_call( req );
}
SERVER_END_REQ;
break;
case TokenSessionId:
if (TokenInformationLength < sizeof(DWORD))
{
ret = STATUS_INFO_LENGTH_MISMATCH;
break;
}
if (!TokenInformation)
{
ret = STATUS_ACCESS_VIOLATION;
break;
}
FIXME("TokenSessionId stub!\n");
ret = STATUS_SUCCESS;
break;
case TokenIntegrityLevel:
FIXME("TokenIntegrityLevel stub!\n");
ret = STATUS_SUCCESS;
break;
default:
FIXME("unimplemented class %u\n", TokenInformationClass);
break;
}
return ret;
}
/******************************************************************************
* NtAdjustGroupsToken [NTDLL.@]
* ZwAdjustGroupsToken [NTDLL.@]
*/
NTSTATUS WINAPI NtAdjustGroupsToken(
HANDLE TokenHandle,
BOOLEAN ResetToDefault,
PTOKEN_GROUPS NewState,
ULONG BufferLength,
PTOKEN_GROUPS PreviousState,
PULONG ReturnLength)
{
FIXME("%p %d %p %u %p %p\n", TokenHandle, ResetToDefault,
NewState, BufferLength, PreviousState, ReturnLength);
return STATUS_NOT_IMPLEMENTED;
}
/******************************************************************************
* NtPrivilegeCheck [NTDLL.@]
* ZwPrivilegeCheck [NTDLL.@]
*/
NTSTATUS WINAPI NtPrivilegeCheck(
HANDLE ClientToken,
PPRIVILEGE_SET RequiredPrivileges,
PBOOLEAN Result)
{
NTSTATUS status;
SERVER_START_REQ( check_token_privileges )
{
req->handle = wine_server_obj_handle( ClientToken );
req->all_required = (RequiredPrivileges->Control & PRIVILEGE_SET_ALL_NECESSARY) != 0;
wine_server_add_data( req, RequiredPrivileges->Privilege,
RequiredPrivileges->PrivilegeCount * sizeof(RequiredPrivileges->Privilege[0]) );
wine_server_set_reply( req, RequiredPrivileges->Privilege,
RequiredPrivileges->PrivilegeCount * sizeof(RequiredPrivileges->Privilege[0]) );
status = wine_server_call( req );
if (status == STATUS_SUCCESS)
*Result = reply->has_privileges != 0;
}
SERVER_END_REQ;
return status;
}
/*
* Misc
*/
......
......@@ -133,8 +133,8 @@
# @ stub NtAccessCheckByTypeResultListAndAuditAlarmByHandle
@ stdcall -syscall NtAddAtom(ptr long ptr)
# @ stub NtAddBootEntry
@ stdcall NtAdjustGroupsToken(long long ptr long ptr ptr)
@ stdcall NtAdjustPrivilegesToken(long long ptr long ptr ptr)
@ stdcall -syscall NtAdjustGroupsToken(long long ptr long ptr ptr)
@ stdcall -syscall NtAdjustPrivilegesToken(long long ptr long ptr ptr)
@ stdcall -syscall NtAlertResumeThread(long ptr)
@ stdcall -syscall NtAlertThread(long)
@ stdcall NtAllocateLocallyUniqueId(ptr)
......@@ -169,7 +169,7 @@
@ stdcall -syscall NtCreateKey(ptr long ptr long ptr long ptr)
@ stdcall -syscall NtCreateKeyTransacted(ptr long ptr long ptr long long ptr)
@ stdcall -syscall NtCreateKeyedEvent(ptr long ptr long)
@ stdcall NtCreateLowBoxToken(ptr long long ptr ptr long ptr long ptr)
@ stdcall -syscall NtCreateLowBoxToken(ptr long long ptr ptr long ptr long ptr)
@ stdcall -syscall NtCreateMailslotFile(ptr long ptr ptr long long long ptr)
@ stdcall -syscall NtCreateMutant(ptr long ptr long)
@ stdcall -syscall NtCreateNamedPipeFile(ptr long ptr ptr long long long long long long long long long ptr)
......@@ -201,7 +201,7 @@
@ stdcall -syscall NtDeviceIoControlFile(long long ptr ptr ptr long ptr long ptr long)
@ stdcall NtDisplayString(ptr)
@ stdcall -syscall NtDuplicateObject(long long long ptr long long long)
@ stdcall NtDuplicateToken(long long ptr long long ptr)
@ stdcall -syscall NtDuplicateToken(long long ptr long long ptr)
# @ stub NtEnumerateBootEntries
@ stub NtEnumerateBus
@ stdcall -syscall NtEnumerateKey(long long long ptr long ptr)
......@@ -226,7 +226,7 @@
@ stub NtGetPlugPlayEvent
@ stdcall NtGetTickCount()
@ stdcall -syscall NtGetWriteWatch(long long ptr long ptr ptr ptr)
@ stdcall NtImpersonateAnonymousToken(long)
@ stdcall -syscall NtImpersonateAnonymousToken(long)
@ stub NtImpersonateClientOfPort
@ stub NtImpersonateThread
@ stub NtInitializeRegistry
......@@ -264,18 +264,18 @@
@ stdcall -syscall NtOpenMutant(ptr long ptr)
@ stub NtOpenObjectAuditAlarm
@ stdcall -syscall NtOpenProcess(ptr long ptr ptr)
@ stdcall NtOpenProcessToken(long long ptr)
@ stdcall NtOpenProcessTokenEx(long long long ptr)
@ stdcall -syscall NtOpenProcessToken(long long ptr)
@ stdcall -syscall NtOpenProcessTokenEx(long long long ptr)
@ stdcall -syscall NtOpenSection(ptr long ptr)
@ stdcall -syscall NtOpenSemaphore(ptr long ptr)
@ stdcall -syscall NtOpenSymbolicLinkObject (ptr long ptr)
@ stdcall -syscall NtOpenThread(ptr long ptr ptr)
@ stdcall NtOpenThreadToken(long long long ptr)
@ stdcall NtOpenThreadTokenEx(long long long long ptr)
@ stdcall -syscall NtOpenThreadToken(long long long ptr)
@ stdcall -syscall NtOpenThreadTokenEx(long long long long ptr)
@ stdcall -syscall NtOpenTimer(ptr long ptr)
@ stub NtPlugPlayControl
@ stdcall -syscall NtPowerInformation(long ptr long ptr long)
@ stdcall NtPrivilegeCheck(ptr ptr ptr)
@ stdcall -syscall NtPrivilegeCheck(ptr ptr ptr)
@ stub NtPrivilegeObjectAuditAlarm
@ stub NtPrivilegedServiceAuditAlarm
@ stdcall -syscall NtProtectVirtualMemory(long ptr ptr long ptr)
......@@ -297,7 +297,7 @@
@ stub NtQueryInformationPort
@ stdcall -syscall NtQueryInformationProcess(long long ptr long ptr)
@ stdcall -syscall NtQueryInformationThread(long long ptr long ptr)
@ stdcall NtQueryInformationToken(long long ptr long ptr)
@ stdcall -syscall NtQueryInformationToken(long long ptr long ptr)
@ stdcall NtQueryInstallUILanguage(ptr)
@ stub NtQueryIntervalProfile
@ stdcall -syscall NtQueryIoCompletion(long long ptr long ptr)
......@@ -379,7 +379,7 @@
@ stdcall -syscall NtSetInformationObject(long long ptr long)
@ stdcall -syscall NtSetInformationProcess(long long ptr long)
@ stdcall -syscall NtSetInformationThread(long long ptr long)
@ stdcall NtSetInformationToken(long long ptr long)
@ stdcall -syscall NtSetInformationToken(long long ptr long)
@ stdcall -syscall NtSetIntervalProfile(long long)
@ stdcall -syscall NtSetIoCompletion(ptr long long long long)
@ stdcall -syscall NtSetLdtEntries(long int64 long int64)
......@@ -1122,8 +1122,8 @@
# @ stub ZwAccessCheckByTypeResultListAndAuditAlarmByHandle
@ stdcall -private -syscall ZwAddAtom(ptr long ptr) NtAddAtom
# @ stub ZwAddBootEntry
@ stdcall -private ZwAdjustGroupsToken(long long ptr long ptr ptr) NtAdjustGroupsToken
@ stdcall -private ZwAdjustPrivilegesToken(long long ptr long ptr ptr) NtAdjustPrivilegesToken
@ stdcall -private -syscall ZwAdjustGroupsToken(long long ptr long ptr ptr) NtAdjustGroupsToken
@ stdcall -private -syscall ZwAdjustPrivilegesToken(long long ptr long ptr ptr) NtAdjustPrivilegesToken
@ stdcall -private -syscall ZwAlertResumeThread(long ptr) NtAlertResumeThread
@ stdcall -private -syscall ZwAlertThread(long) NtAlertThread
@ stdcall -private ZwAllocateLocallyUniqueId(ptr) NtAllocateLocallyUniqueId
......@@ -1158,6 +1158,7 @@
@ stdcall -private -syscall ZwCreateKey(ptr long ptr long ptr long ptr) NtCreateKey
@ stdcall -private -syscall ZwCreateKeyTransacted(ptr long ptr long ptr long long ptr) NtCreateKeyTransacted
@ stdcall -private -syscall ZwCreateKeyedEvent(ptr long ptr long) NtCreateKeyedEvent
@ stdcall -private -syscall ZwCreateLowBoxToken(ptr long long ptr ptr long ptr long ptr) NtCreateLowBoxToken
@ stdcall -private -syscall ZwCreateMailslotFile(ptr long ptr ptr long long long ptr) NtCreateMailslotFile
@ stdcall -private -syscall ZwCreateMutant(ptr long ptr long) NtCreateMutant
@ stdcall -private -syscall ZwCreateNamedPipeFile(ptr long ptr ptr long long long long long long long long long ptr) NtCreateNamedPipeFile
......@@ -1188,7 +1189,7 @@
@ stdcall -private -syscall ZwDeviceIoControlFile(long long ptr ptr ptr long ptr long ptr long) NtDeviceIoControlFile
@ stdcall -private ZwDisplayString(ptr) NtDisplayString
@ stdcall -private -syscall ZwDuplicateObject(long long long ptr long long long) NtDuplicateObject
@ stdcall -private ZwDuplicateToken(long long ptr long long ptr) NtDuplicateToken
@ stdcall -private -syscall ZwDuplicateToken(long long ptr long long ptr) NtDuplicateToken
# @ stub ZwEnumerateBootEntries
@ stub ZwEnumerateBus
@ stdcall -private -syscall ZwEnumerateKey(long long long ptr long ptr) NtEnumerateKey
......@@ -1213,7 +1214,7 @@
@ stub ZwGetPlugPlayEvent
@ stdcall -private ZwGetTickCount() NtGetTickCount
@ stdcall -private -syscall ZwGetWriteWatch(long long ptr long ptr ptr ptr) NtGetWriteWatch
@ stdcall -private ZwImpersonateAnonymousToken(long) NtImpersonateAnonymousToken
@ stdcall -private -syscall ZwImpersonateAnonymousToken(long) NtImpersonateAnonymousToken
@ stub ZwImpersonateClientOfPort
@ stub ZwImpersonateThread
@ stub ZwInitializeRegistry
......@@ -1251,18 +1252,18 @@
@ stdcall -private -syscall ZwOpenMutant(ptr long ptr) NtOpenMutant
@ stub ZwOpenObjectAuditAlarm
@ stdcall -private -syscall ZwOpenProcess(ptr long ptr ptr) NtOpenProcess
@ stdcall -private ZwOpenProcessToken(long long ptr) NtOpenProcessToken
@ stdcall -private ZwOpenProcessTokenEx(long long long ptr) NtOpenProcessTokenEx
@ stdcall -private -syscall ZwOpenProcessToken(long long ptr) NtOpenProcessToken
@ stdcall -private -syscall ZwOpenProcessTokenEx(long long long ptr) NtOpenProcessTokenEx
@ stdcall -private -syscall ZwOpenSection(ptr long ptr) NtOpenSection
@ stdcall -private -syscall ZwOpenSemaphore(ptr long ptr) NtOpenSemaphore
@ stdcall -private -syscall ZwOpenSymbolicLinkObject (ptr long ptr) NtOpenSymbolicLinkObject
@ stdcall -private -syscall ZwOpenThread(ptr long ptr ptr) NtOpenThread
@ stdcall -private ZwOpenThreadToken(long long long ptr) NtOpenThreadToken
@ stdcall -private ZwOpenThreadTokenEx(long long long long ptr) NtOpenThreadTokenEx
@ stdcall -private -syscall ZwOpenThreadToken(long long long ptr) NtOpenThreadToken
@ stdcall -private -syscall ZwOpenThreadTokenEx(long long long long ptr) NtOpenThreadTokenEx
@ stdcall -private -syscall ZwOpenTimer(ptr long ptr) NtOpenTimer
@ stub ZwPlugPlayControl
@ stdcall -private -syscall ZwPowerInformation(long ptr long ptr long) NtPowerInformation
@ stdcall -private ZwPrivilegeCheck(ptr ptr ptr) NtPrivilegeCheck
@ stdcall -private -syscall ZwPrivilegeCheck(ptr ptr ptr) NtPrivilegeCheck
@ stub ZwPrivilegeObjectAuditAlarm
@ stub ZwPrivilegedServiceAuditAlarm
@ stdcall -private -syscall ZwProtectVirtualMemory(long ptr ptr long ptr) NtProtectVirtualMemory
......@@ -1284,7 +1285,7 @@
@ stub ZwQueryInformationPort
@ stdcall -private -syscall ZwQueryInformationProcess(long long ptr long ptr) NtQueryInformationProcess
@ stdcall -private -syscall ZwQueryInformationThread(long long ptr long ptr) NtQueryInformationThread
@ stdcall -private ZwQueryInformationToken(long long ptr long ptr) NtQueryInformationToken
@ stdcall -private -syscall ZwQueryInformationToken(long long ptr long ptr) NtQueryInformationToken
@ stdcall -private ZwQueryInstallUILanguage(ptr) NtQueryInstallUILanguage
@ stub ZwQueryIntervalProfile
@ stdcall -private -syscall ZwQueryIoCompletion(long long ptr long ptr) NtQueryIoCompletion
......@@ -1366,7 +1367,7 @@
@ stdcall -private -syscall ZwSetInformationObject(long long ptr long) NtSetInformationObject
@ stdcall -private -syscall ZwSetInformationProcess(long long ptr long) NtSetInformationProcess
@ stdcall -private -syscall ZwSetInformationThread(long long ptr long) NtSetInformationThread
@ stdcall -private ZwSetInformationToken(long long ptr long) NtSetInformationToken
@ stdcall -private -syscall ZwSetInformationToken(long long ptr long) NtSetInformationToken
@ stdcall -private -syscall ZwSetIntervalProfile(long long) NtSetIntervalProfile
@ stdcall -private -syscall ZwSetIoCompletion(ptr long long long long) NtSetIoCompletion
@ stdcall -private -syscall ZwSetLdtEntries(long int64 long int64) NtSetLdtEntries
......
......@@ -57,7 +57,6 @@ extern RUNTIME_FUNCTION *lookup_function_info( ULONG_PTR pc, ULONG_PTR *base, LD
/* debug helpers */
extern LPCSTR debugstr_us( const UNICODE_STRING *str ) DECLSPEC_HIDDEN;
extern LPCSTR debugstr_ObjectAttributes(const OBJECT_ATTRIBUTES *oa) DECLSPEC_HIDDEN;
/* init routines */
extern void version_init(void) DECLSPEC_HIDDEN;
......@@ -71,8 +70,6 @@ extern NTSTATUS restart_process( RTL_USER_PROCESS_PARAMETERS *params, NTSTATUS s
/* server support */
extern BOOL is_wow64 DECLSPEC_HIDDEN;
extern NTSTATUS alloc_object_attributes( const OBJECT_ATTRIBUTES *attr, struct object_attributes **ret,
data_size_t *ret_len ) DECLSPEC_HIDDEN;
/* module handling */
extern LIST_ENTRY tls_links DECLSPEC_HIDDEN;
......
......@@ -1604,16 +1604,6 @@ RtlImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
}
/******************************************************************************
* NtImpersonateAnonymousToken [NTDLL.@]
*/
NTSTATUS WINAPI
NtImpersonateAnonymousToken(HANDLE thread)
{
FIXME("(%p): stub\n", thread);
return STATUS_NOT_IMPLEMENTED;
}
/******************************************************************************
* NtAccessCheck [NTDLL.@]
* ZwAccessCheck [NTDLL.@]
*
......
......@@ -37,89 +37,6 @@
#include "wine/debug.h"
#include "ntdll_misc.h"
/* creates a struct security_descriptor and contained information in one contiguous piece of memory */
NTSTATUS alloc_object_attributes( const OBJECT_ATTRIBUTES *attr, struct object_attributes **ret,
data_size_t *ret_len )
{
unsigned int len = sizeof(**ret);
PSID owner = NULL, group = NULL;
ACL *dacl, *sacl;
BOOLEAN dacl_present, sacl_present, defaulted;
PSECURITY_DESCRIPTOR sd;
NTSTATUS status;
*ret = NULL;
*ret_len = 0;
if (!attr) return STATUS_SUCCESS;
if (attr->Length != sizeof(*attr)) return STATUS_INVALID_PARAMETER;
if ((sd = attr->SecurityDescriptor))
{
len += sizeof(struct security_descriptor);
if ((status = RtlGetOwnerSecurityDescriptor( sd, &owner, &defaulted ))) return status;
if ((status = RtlGetGroupSecurityDescriptor( sd, &group, &defaulted ))) return status;
if ((status = RtlGetSaclSecurityDescriptor( sd, &sacl_present, &sacl, &defaulted ))) return status;
if ((status = RtlGetDaclSecurityDescriptor( sd, &dacl_present, &dacl, &defaulted ))) return status;
if (owner) len += RtlLengthSid( owner );
if (group) len += RtlLengthSid( group );
if (sacl_present && sacl) len += sacl->AclSize;
if (dacl_present && dacl) len += dacl->AclSize;
/* fix alignment for the Unicode name that follows the structure */
len = (len + sizeof(WCHAR) - 1) & ~(sizeof(WCHAR) - 1);
}
if (attr->ObjectName)
{
if (attr->ObjectName->Length & (sizeof(WCHAR) - 1)) return STATUS_OBJECT_NAME_INVALID;
len += attr->ObjectName->Length;
}
else if (attr->RootDirectory) return STATUS_OBJECT_NAME_INVALID;
len = (len + 3) & ~3; /* DWORD-align the entire structure */
*ret = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, len );
if (!*ret) return STATUS_NO_MEMORY;
(*ret)->rootdir = wine_server_obj_handle( attr->RootDirectory );
(*ret)->attributes = attr->Attributes;
if (attr->SecurityDescriptor)
{
struct security_descriptor *descr = (struct security_descriptor *)(*ret + 1);
unsigned char *ptr = (unsigned char *)(descr + 1);
descr->control = ((SECURITY_DESCRIPTOR *)sd)->Control & ~SE_SELF_RELATIVE;
if (owner) descr->owner_len = RtlLengthSid( owner );
if (group) descr->group_len = RtlLengthSid( group );
if (sacl_present && sacl) descr->sacl_len = sacl->AclSize;
if (dacl_present && dacl) descr->dacl_len = dacl->AclSize;
memcpy( ptr, owner, descr->owner_len );
ptr += descr->owner_len;
memcpy( ptr, group, descr->group_len );
ptr += descr->group_len;
memcpy( ptr, sacl, descr->sacl_len );
ptr += descr->sacl_len;
memcpy( ptr, dacl, descr->dacl_len );
(*ret)->sd_len = (sizeof(*descr) + descr->owner_len + descr->group_len + descr->sacl_len +
descr->dacl_len + sizeof(WCHAR) - 1) & ~(sizeof(WCHAR) - 1);
}
if (attr->ObjectName)
{
unsigned char *ptr = (unsigned char *)(*ret + 1) + (*ret)->sd_len;
(*ret)->name_len = attr->ObjectName->Length;
memcpy( ptr, attr->ObjectName->Buffer, (*ret)->name_len );
}
*ret_len = len;
return STATUS_SUCCESS;
}
/******************************************************************
* RtlRunOnceInitialize (NTDLL.@)
......
/*
* Security functions
*
* Copyright 1996-1998 Marcus Meissner
* Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#if 0
#pragma makedep unix
#endif
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
#include "unix_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
/***********************************************************************
* NtOpenProcessToken (NTDLL.@)
*/
NTSTATUS WINAPI NtOpenProcessToken( HANDLE process, DWORD access, HANDLE *handle )
{
return NtOpenProcessTokenEx( process, access, 0, handle );
}
/***********************************************************************
* NtOpenProcessTokenEx (NTDLL.@)
*/
NTSTATUS WINAPI NtOpenProcessTokenEx( HANDLE process, DWORD access, DWORD attributes, HANDLE *handle )
{
NTSTATUS ret;
TRACE( "(%p,0x%08x,0x%08x,%p)\n", process, access, attributes, handle );
SERVER_START_REQ( open_token )
{
req->handle = wine_server_obj_handle( process );
req->access = access;
req->attributes = attributes;
req->flags = 0;
ret = wine_server_call( req );
if (!ret) *handle = wine_server_ptr_handle( reply->token );
}
SERVER_END_REQ;
return ret;
}
/***********************************************************************
* NtOpenThreadToken (NTDLL.@)
*/
NTSTATUS WINAPI NtOpenThreadToken( HANDLE thread, DWORD access, BOOLEAN self, HANDLE *handle )
{
return NtOpenThreadTokenEx( thread, access, self, 0, handle );
}
/***********************************************************************
* NtOpenThreadTokenEx (NTDLL.@)
*/
NTSTATUS WINAPI NtOpenThreadTokenEx( HANDLE thread, DWORD access, BOOLEAN self, DWORD attributes,
HANDLE *handle )
{
NTSTATUS ret;
TRACE( "(%p,0x%08x,%u,0x%08x,%p)\n", thread, access, self, attributes, handle );
SERVER_START_REQ( open_token )
{
req->handle = wine_server_obj_handle( thread );
req->access = access;
req->attributes = attributes;
req->flags = OPEN_TOKEN_THREAD;
if (self) req->flags |= OPEN_TOKEN_AS_SELF;
ret = wine_server_call( req );
if (!ret) *handle = wine_server_ptr_handle( reply->token );
}
SERVER_END_REQ;
return ret;
}
/***********************************************************************
* NtDuplicateToken (NTDLL.@)
*/
NTSTATUS WINAPI NtDuplicateToken( HANDLE token, ACCESS_MASK access, OBJECT_ATTRIBUTES *attr,
SECURITY_IMPERSONATION_LEVEL level, TOKEN_TYPE type, HANDLE *handle )
{
NTSTATUS status;
data_size_t len;
struct object_attributes *objattr;
if ((status = alloc_object_attributes( attr, &objattr, &len ))) return status;
if (attr && attr->SecurityQualityOfService)
{
SECURITY_QUALITY_OF_SERVICE *qos = attr->SecurityQualityOfService;
TRACE( "ObjectAttributes->SecurityQualityOfService = {%d, %d, %d, %s}\n",
qos->Length, qos->ImpersonationLevel, qos->ContextTrackingMode,
qos->EffectiveOnly ? "TRUE" : "FALSE");
level = qos->ImpersonationLevel;
}
SERVER_START_REQ( duplicate_token )
{
req->handle = wine_server_obj_handle( token );
req->access = access;
req->primary = (type == TokenPrimary);
req->impersonation_level = level;
wine_server_add_data( req, objattr, len );
status = wine_server_call( req );
if (!status) *handle = wine_server_ptr_handle( reply->new_handle );
}
SERVER_END_REQ;
free( objattr );
return status;
}
/***********************************************************************
* NtQueryInformationToken (NTDLL.@)
*/
NTSTATUS WINAPI NtQueryInformationToken( HANDLE token, TOKEN_INFORMATION_CLASS class,
void *info, ULONG length, ULONG *retlen )
{
static const ULONG info_len [] =
{
0,
0, /* TokenUser */
0, /* TokenGroups */
0, /* TokenPrivileges */
0, /* TokenOwner */
0, /* TokenPrimaryGroup */
0, /* TokenDefaultDacl */
sizeof(TOKEN_SOURCE), /* TokenSource */
sizeof(TOKEN_TYPE), /* TokenType */
sizeof(SECURITY_IMPERSONATION_LEVEL), /* TokenImpersonationLevel */
sizeof(TOKEN_STATISTICS), /* TokenStatistics */
0, /* TokenRestrictedSids */
sizeof(DWORD), /* TokenSessionId */
0, /* TokenGroupsAndPrivileges */
0, /* TokenSessionReference */
0, /* TokenSandBoxInert */
0, /* TokenAuditPolicy */
0, /* TokenOrigin */
sizeof(TOKEN_ELEVATION_TYPE), /* TokenElevationType */
0, /* TokenLinkedToken */
sizeof(TOKEN_ELEVATION), /* TokenElevation */
0, /* TokenHasRestrictions */
0, /* TokenAccessInformation */
0, /* TokenVirtualizationAllowed */
sizeof(DWORD), /* TokenVirtualizationEnabled */
sizeof(TOKEN_MANDATORY_LABEL) + sizeof(SID), /* TokenIntegrityLevel [sizeof(SID) includes one SubAuthority] */
0, /* TokenUIAccess */
0, /* TokenMandatoryPolicy */
0, /* TokenLogonSid */
sizeof(DWORD), /* TokenIsAppContainer */
0, /* TokenCapabilities */
sizeof(TOKEN_APPCONTAINER_INFORMATION) + sizeof(SID), /* TokenAppContainerSid */
0, /* TokenAppContainerNumber */
0, /* TokenUserClaimAttributes*/
0, /* TokenDeviceClaimAttributes */
0, /* TokenRestrictedUserClaimAttributes */
0, /* TokenRestrictedDeviceClaimAttributes */
0, /* TokenDeviceGroups */
0, /* TokenRestrictedDeviceGroups */
0, /* TokenSecurityAttributes */
0, /* TokenIsRestricted */
0 /* TokenProcessTrustLevel */
};
ULONG len = 0;
NTSTATUS status = STATUS_SUCCESS;
TRACE( "(%p,%d,%p,%d,%p)\n", token, class, info, length, retlen );
if (class < MaxTokenInfoClass) len = info_len[class];
if (retlen) *retlen = len;
if (length < len) return STATUS_BUFFER_TOO_SMALL;
switch (class)
{
case TokenUser:
SERVER_START_REQ( get_token_sid )
{
TOKEN_USER *tuser = info;
PSID sid = tuser + 1;
DWORD sid_len = length < sizeof(TOKEN_USER) ? 0 : length - sizeof(TOKEN_USER);
req->handle = wine_server_obj_handle( token );
req->which_sid = class;
wine_server_set_reply( req, sid, sid_len );
status = wine_server_call( req );
if (retlen) *retlen = reply->sid_len + sizeof(TOKEN_USER);
if (status == STATUS_SUCCESS)
{
tuser->User.Sid = sid;
tuser->User.Attributes = 0;
}
}
SERVER_END_REQ;
break;
case TokenGroups:
{
/* reply buffer is always shorter than output one */
void *buffer = malloc( length );
SERVER_START_REQ( get_token_groups )
{
TOKEN_GROUPS *groups = info;
req->handle = wine_server_obj_handle( token );
wine_server_set_reply( req, buffer, length );
status = wine_server_call( req );
if (status == STATUS_BUFFER_TOO_SMALL)
{
if (retlen) *retlen = reply->user_len;
}
else if (status == STATUS_SUCCESS)
{
struct token_groups *tg = buffer;
unsigned int *attr = (unsigned int *)(tg + 1);
ULONG i;
const int non_sid_portion = (sizeof(struct token_groups) + tg->count * sizeof(unsigned int));
SID *sids = (SID *)((char *)info + FIELD_OFFSET( TOKEN_GROUPS, Groups[tg->count] ));
if (retlen) *retlen = reply->user_len;
groups->GroupCount = tg->count;
memcpy( sids, (char *)buffer + non_sid_portion,
reply->user_len - offsetof( TOKEN_GROUPS, Groups[tg->count] ));
for (i = 0; i < tg->count; i++)
{
groups->Groups[i].Attributes = attr[i];
groups->Groups[i].Sid = sids;
sids = (SID *)((char *)sids + offsetof( SID, SubAuthority[sids->SubAuthorityCount] ));
}
}
else if (retlen) *retlen = 0;
}
SERVER_END_REQ;
free( buffer );
break;
}
case TokenPrimaryGroup:
SERVER_START_REQ( get_token_sid )
{
TOKEN_PRIMARY_GROUP *tgroup = info;
PSID sid = tgroup + 1;
DWORD sid_len = length < sizeof(TOKEN_PRIMARY_GROUP) ? 0 : length - sizeof(TOKEN_PRIMARY_GROUP);
req->handle = wine_server_obj_handle( token );
req->which_sid = class;
wine_server_set_reply( req, sid, sid_len );
status = wine_server_call( req );
if (retlen) *retlen = reply->sid_len + sizeof(TOKEN_PRIMARY_GROUP);
if (status == STATUS_SUCCESS) tgroup->PrimaryGroup = sid;
}
SERVER_END_REQ;
break;
case TokenPrivileges:
SERVER_START_REQ( get_token_privileges )
{
TOKEN_PRIVILEGES *tpriv = info;
req->handle = wine_server_obj_handle( token );
if (tpriv && length > FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ))
wine_server_set_reply( req, tpriv->Privileges, length - FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ) );
status = wine_server_call( req );
if (retlen) *retlen = FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ) + reply->len;
if (tpriv) tpriv->PrivilegeCount = reply->len / sizeof(LUID_AND_ATTRIBUTES);
}
SERVER_END_REQ;
break;
case TokenOwner:
SERVER_START_REQ( get_token_sid )
{
TOKEN_OWNER *towner = info;
PSID sid = towner + 1;
DWORD sid_len = length < sizeof(TOKEN_OWNER) ? 0 : length - sizeof(TOKEN_OWNER);
req->handle = wine_server_obj_handle( token );
req->which_sid = class;
wine_server_set_reply( req, sid, sid_len );
status = wine_server_call( req );
if (retlen) *retlen = reply->sid_len + sizeof(TOKEN_OWNER);
if (status == STATUS_SUCCESS) towner->Owner = sid;
}
SERVER_END_REQ;
break;
case TokenImpersonationLevel:
SERVER_START_REQ( get_token_impersonation_level )
{
SECURITY_IMPERSONATION_LEVEL *level = info;
req->handle = wine_server_obj_handle( token );
status = wine_server_call( req );
if (status == STATUS_SUCCESS) *level = reply->impersonation_level;
}
SERVER_END_REQ;
break;
case TokenStatistics:
SERVER_START_REQ( get_token_statistics )
{
TOKEN_STATISTICS *statistics = info;
req->handle = wine_server_obj_handle( token );
status = wine_server_call( req );
if (status == STATUS_SUCCESS)
{
statistics->TokenId.LowPart = reply->token_id.low_part;
statistics->TokenId.HighPart = reply->token_id.high_part;
statistics->AuthenticationId.LowPart = 0; /* FIXME */
statistics->AuthenticationId.HighPart = 0; /* FIXME */
statistics->ExpirationTime.u.HighPart = 0x7fffffff;
statistics->ExpirationTime.u.LowPart = 0xffffffff;
statistics->TokenType = reply->primary ? TokenPrimary : TokenImpersonation;
statistics->ImpersonationLevel = reply->impersonation_level;
/* kernel information not relevant to us */
statistics->DynamicCharged = 0;
statistics->DynamicAvailable = 0;
statistics->GroupCount = reply->group_count;
statistics->PrivilegeCount = reply->privilege_count;
statistics->ModifiedId.LowPart = reply->modified_id.low_part;
statistics->ModifiedId.HighPart = reply->modified_id.high_part;
}
}
SERVER_END_REQ;
break;
case TokenType:
SERVER_START_REQ( get_token_statistics )
{
TOKEN_TYPE *type = info;
req->handle = wine_server_obj_handle( token );
status = wine_server_call( req );
if (status == STATUS_SUCCESS) *type = reply->primary ? TokenPrimary : TokenImpersonation;
}
SERVER_END_REQ;
break;
case TokenDefaultDacl:
SERVER_START_REQ( get_token_default_dacl )
{
TOKEN_DEFAULT_DACL *default_dacl = info;
ACL *acl = (ACL *)(default_dacl + 1);
DWORD acl_len = length < sizeof(TOKEN_DEFAULT_DACL) ? 0 : length - sizeof(TOKEN_DEFAULT_DACL);
req->handle = wine_server_obj_handle( token );
wine_server_set_reply( req, acl, acl_len );
status = wine_server_call( req );
if (retlen) *retlen = reply->acl_len + sizeof(TOKEN_DEFAULT_DACL);
if (status == STATUS_SUCCESS)
{
if (reply->acl_len)
default_dacl->DefaultDacl = acl;
else
default_dacl->DefaultDacl = NULL;
}
}
SERVER_END_REQ;
break;
case TokenElevationType:
{
TOKEN_ELEVATION_TYPE *type = info;
FIXME("QueryInformationToken( ..., TokenElevationType, ...) semi-stub\n");
*type = TokenElevationTypeFull;
}
break;
case TokenElevation:
{
TOKEN_ELEVATION *elevation = info;
FIXME("QueryInformationToken( ..., TokenElevation, ...) semi-stub\n");
elevation->TokenIsElevated = TRUE;
}
break;
case TokenSessionId:
{
*(DWORD *)info = 0;
FIXME("QueryInformationToken( ..., TokenSessionId, ...) semi-stub\n");
}
break;
case TokenVirtualizationEnabled:
{
*(DWORD *)info = 0;
TRACE("QueryInformationToken( ..., TokenVirtualizationEnabled, ...) semi-stub\n");
}
break;
case TokenIntegrityLevel:
{
/* report always "S-1-16-12288" (high mandatory level) for now */
static const SID high_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
{SECURITY_MANDATORY_HIGH_RID}};
TOKEN_MANDATORY_LABEL *tml = info;
PSID psid = tml + 1;
tml->Label.Sid = psid;
tml->Label.Attributes = SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED;
memcpy( psid, &high_level, sizeof(SID) );
}
break;
case TokenAppContainerSid:
{
TOKEN_APPCONTAINER_INFORMATION *container = info;
FIXME("QueryInformationToken( ..., TokenAppContainerSid, ...) semi-stub\n");
container->TokenAppContainer = NULL;
}
break;
case TokenIsAppContainer:
{
TRACE("TokenIsAppContainer semi-stub\n");
*(DWORD *)info = 0;
break;
}
case TokenLogonSid:
SERVER_START_REQ( get_token_sid )
{
TOKEN_GROUPS * groups = info;
PSID sid = groups + 1;
DWORD sid_len = length < sizeof(TOKEN_GROUPS) ? 0 : length - sizeof(TOKEN_GROUPS);
req->handle = wine_server_obj_handle( token );
req->which_sid = class;
wine_server_set_reply( req, sid, sid_len );
status = wine_server_call( req );
if (retlen) *retlen = reply->sid_len + sizeof(TOKEN_GROUPS);
if (status == STATUS_SUCCESS)
{
groups->GroupCount = 1;
groups->Groups[0].Sid = sid;
groups->Groups[0].Attributes = 0;
}
}
SERVER_END_REQ;
break;
default:
ERR( "Unhandled token information class %u\n", class );
return STATUS_NOT_IMPLEMENTED;
}
return status;
}
/***********************************************************************
* NtSetInformationToken (NTDLL.@)
*/
NTSTATUS WINAPI NtSetInformationToken( HANDLE token, TOKEN_INFORMATION_CLASS class,
void *info, ULONG length )
{
NTSTATUS ret = STATUS_NOT_IMPLEMENTED;
TRACE( "%p %d %p %u\n", token, class, info, length );
switch (class)
{
case TokenDefaultDacl:
if (length < sizeof(TOKEN_DEFAULT_DACL))
{
ret = STATUS_INFO_LENGTH_MISMATCH;
break;
}
if (!info)
{
ret = STATUS_ACCESS_VIOLATION;
break;
}
SERVER_START_REQ( set_token_default_dacl )
{
ACL *acl = ((TOKEN_DEFAULT_DACL *)info)->DefaultDacl;
WORD size;
if (acl) size = acl->AclSize;
else size = 0;
req->handle = wine_server_obj_handle( token );
wine_server_add_data( req, acl, size );
ret = wine_server_call( req );
}
SERVER_END_REQ;
break;
case TokenSessionId:
if (length < sizeof(DWORD))
{
ret = STATUS_INFO_LENGTH_MISMATCH;
break;
}
if (!info)
{
ret = STATUS_ACCESS_VIOLATION;
break;
}
FIXME("TokenSessionId stub!\n");
ret = STATUS_SUCCESS;
break;
case TokenIntegrityLevel:
FIXME( "TokenIntegrityLevel stub!\n" );
ret = STATUS_SUCCESS;
break;
default:
FIXME( "unimplemented class %u\n", class );
break;
}
return ret;
}
/***********************************************************************
* NtCreateLowBoxToken (NTDLL.@)
*/
NTSTATUS WINAPI NtCreateLowBoxToken( HANDLE *token_handle, HANDLE token, ACCESS_MASK access,
OBJECT_ATTRIBUTES *attr, SID *sid, ULONG count,
SID_AND_ATTRIBUTES *capabilities, ULONG handle_count, HANDLE *handle )
{
FIXME("(%p, %p, %x, %p, %p, %u, %p, %u, %p): stub\n",
token_handle, token, access, attr, sid, count, capabilities, handle_count, handle );
/* we need to return a NULL handle since later it will be passed to NtClose and that must not fail */
*token_handle = NULL;
return STATUS_SUCCESS;
}
/***********************************************************************
* NtAdjustGroupsToken (NTDLL.@)
*/
NTSTATUS WINAPI NtAdjustGroupsToken( HANDLE token, BOOLEAN reset, TOKEN_GROUPS *groups,
ULONG length, TOKEN_GROUPS *prev, ULONG *retlen )
{
FIXME( "%p %d %p %u %p %p\n", token, reset, groups, length, prev, retlen );
return STATUS_NOT_IMPLEMENTED;
}
/***********************************************************************
* NtAdjustPrivilegesToken (NTDLL.@)
*/
NTSTATUS WINAPI NtAdjustPrivilegesToken( HANDLE token, BOOLEAN disable, TOKEN_PRIVILEGES *privs,
DWORD length, TOKEN_PRIVILEGES *prev, DWORD *retlen )
{
NTSTATUS ret;
TRACE( "(%p,0x%08x,%p,0x%08x,%p,%p)\n", token, disable, privs, length, prev, retlen );
SERVER_START_REQ( adjust_token_privileges )
{
req->handle = wine_server_obj_handle( token );
req->disable_all = disable;
req->get_modified_state = (prev != NULL);
if (!disable)
wine_server_add_data( req, privs->Privileges,
privs->PrivilegeCount * sizeof(privs->Privileges[0]) );
if (prev && length >= FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ))
wine_server_set_reply( req, prev->Privileges,
length - FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ) );
ret = wine_server_call( req );
if (prev)
{
if (retlen) *retlen = reply->len + FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges );
prev->PrivilegeCount = reply->len / sizeof(LUID_AND_ATTRIBUTES);
}
}
SERVER_END_REQ;
return ret;
}
/***********************************************************************
* NtPrivilegeCheck (NTDLL.@)
*/
NTSTATUS WINAPI NtPrivilegeCheck( HANDLE token, PRIVILEGE_SET *privs, BOOLEAN *res )
{
NTSTATUS status;
SERVER_START_REQ( check_token_privileges )
{
req->handle = wine_server_obj_handle( token );
req->all_required = (privs->Control & PRIVILEGE_SET_ALL_NECESSARY) != 0;
wine_server_add_data( req, privs->Privilege, privs->PrivilegeCount * sizeof(privs->Privilege[0]) );
wine_server_set_reply( req, privs->Privilege, privs->PrivilegeCount * sizeof(privs->Privilege[0]) );
status = wine_server_call( req );
if (status == STATUS_SUCCESS) *res = reply->has_privileges != 0;
}
SERVER_END_REQ;
return status;
}
/***********************************************************************
* NtImpersonateAnonymousToken (NTDLL.@)
*/
NTSTATUS WINAPI NtImpersonateAnonymousToken( HANDLE thread )
{
FIXME( "(%p): stub\n", thread );
return STATUS_NOT_IMPLEMENTED;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment