ntdll: Move the security system calls to the Unix library.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2020-07-20 12:25:12 +02:00
parent dd77ff754b
commit f298db7254
5 changed files with 209 additions and 339 deletions

View File

@ -105,32 +105,6 @@ NTSTATUS WINAPI NtDisplayString ( PUNICODE_STRING string )
return ret;
}
/******************************************************************************
* NtAllocateLocallyUniqueId (NTDLL.@)
*/
NTSTATUS WINAPI NtAllocateLocallyUniqueId(PLUID Luid)
{
NTSTATUS status;
TRACE("%p\n", Luid);
if (!Luid)
return STATUS_ACCESS_VIOLATION;
SERVER_START_REQ( allocate_locally_unique_id )
{
status = wine_server_call( req );
if (!status)
{
Luid->LowPart = reply->luid.low_part;
Luid->HighPart = reply->luid.high_part;
}
}
SERVER_END_REQ;
return status;
}
/******************************************************************************
* VerSetConditionMask (NTDLL.@)
*/
@ -161,19 +135,3 @@ ULONGLONG WINAPI VerSetConditionMask( ULONGLONG dwlConditionMask, DWORD dwTypeBi
dwlConditionMask |= dwConditionMask << 0*3;
return dwlConditionMask;
}
/******************************************************************************
* NtAccessCheckAndAuditAlarm (NTDLL.@)
* ZwAccessCheckAndAuditAlarm (NTDLL.@)
*/
NTSTATUS WINAPI NtAccessCheckAndAuditAlarm(PUNICODE_STRING SubsystemName, HANDLE HandleId, PUNICODE_STRING ObjectTypeName,
PUNICODE_STRING ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor,
ACCESS_MASK DesiredAccess, PGENERIC_MAPPING GenericMapping, BOOLEAN ObjectCreation,
PACCESS_MASK GrantedAccess, PBOOLEAN AccessStatus, PBOOLEAN GenerateOnClose)
{
FIXME("(%s, %p, %s, %p, 0x%08x, %p, %d, %p, %p, %p), stub\n", debugstr_us(SubsystemName), HandleId,
debugstr_us(ObjectTypeName), SecurityDescriptor, DesiredAccess, GenericMapping, ObjectCreation,
GrantedAccess, AccessStatus, GenerateOnClose);
return STATUS_NOT_IMPLEMENTED;
}

View File

@ -124,8 +124,8 @@
@ extern NlsMbCodePageTag
@ extern NlsMbOemCodePageTag
@ stdcall -syscall NtAcceptConnectPort(ptr long ptr long ptr ptr)
@ stdcall NtAccessCheck(ptr long long ptr ptr ptr ptr ptr)
@ stdcall NtAccessCheckAndAuditAlarm(ptr long ptr ptr ptr long ptr long ptr ptr ptr)
@ stdcall -syscall NtAccessCheck(ptr long long ptr ptr ptr ptr ptr)
@ stdcall -syscall NtAccessCheckAndAuditAlarm(ptr long ptr ptr ptr long ptr long ptr ptr ptr)
# @ stub NtAccessCheckByType
# @ stub NtAccessCheckByTypeAndAuditAlarm
# @ stub NtAccessCheckByTypeResultList
@ -137,9 +137,9 @@
@ stdcall -syscall NtAdjustPrivilegesToken(long long ptr long ptr ptr)
@ stdcall -syscall NtAlertResumeThread(long ptr)
@ stdcall -syscall NtAlertThread(long)
@ stdcall NtAllocateLocallyUniqueId(ptr)
@ stdcall -syscall NtAllocateLocallyUniqueId(ptr)
# @ stub NtAllocateUserPhysicalPages
@ stdcall NtAllocateUuids(ptr ptr ptr ptr)
@ stdcall -syscall NtAllocateUuids(ptr ptr ptr ptr)
@ stdcall -syscall NtAllocateVirtualMemory(long ptr long ptr long long)
@ stdcall -syscall NtAreMappedFilesTheSame(ptr ptr)
@ stdcall -syscall NtAssignProcessToJobObject(long long)
@ -311,7 +311,7 @@
# @ stub NtQueryPortInformationProcess
# @ stub NtQueryQuotaInformationFile
@ stdcall -syscall NtQuerySection(long long ptr long ptr)
@ stdcall NtQuerySecurityObject(long long ptr long ptr)
@ stdcall -syscall NtQuerySecurityObject(long long ptr long ptr)
@ stdcall -syscall NtQuerySemaphore (long long ptr long ptr)
@ stdcall -syscall NtQuerySymbolicLinkObject(long ptr ptr)
@ stdcall -syscall NtQuerySystemEnvironmentValue(ptr ptr long ptr)
@ -388,7 +388,7 @@
@ stub NtSetLowWaitHighThread
@ stdcall -syscall NtSetPowerRequest(long long)
# @ stub NtSetQuotaInformationFile
@ stdcall NtSetSecurityObject(long long ptr)
@ stdcall -syscall NtSetSecurityObject(long long ptr)
@ stub NtSetSystemEnvironmentValue
# @ stub NtSetSystemEnvironmentValueEx
@ stdcall -syscall NtSetSystemInformation(long ptr long)
@ -1113,8 +1113,8 @@
@ stdcall WinSqmSetDWORD(ptr long long)
@ stdcall WinSqmStartSession(ptr long long)
@ stdcall -private -syscall ZwAcceptConnectPort(ptr long ptr long ptr ptr) NtAcceptConnectPort
@ stdcall -private ZwAccessCheck(ptr long long ptr ptr ptr ptr ptr) NtAccessCheck
@ stdcall -private ZwAccessCheckAndAuditAlarm(ptr long ptr ptr ptr long ptr long ptr ptr ptr) NtAccessCheckAndAuditAlarm
@ stdcall -private -syscall ZwAccessCheck(ptr long long ptr ptr ptr ptr ptr) NtAccessCheck
@ stdcall -private -syscall ZwAccessCheckAndAuditAlarm(ptr long ptr ptr ptr long ptr long ptr ptr ptr) NtAccessCheckAndAuditAlarm
# @ stub ZwAccessCheckByType
# @ stub ZwAccessCheckByTypeAndAuditAlarm
# @ stub ZwAccessCheckByTypeResultList
@ -1126,9 +1126,9 @@
@ 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
@ stdcall -private -syscall ZwAllocateLocallyUniqueId(ptr) NtAllocateLocallyUniqueId
# @ stub ZwAllocateUserPhysicalPages
@ stdcall -private ZwAllocateUuids(ptr ptr ptr ptr) NtAllocateUuids
@ stdcall -private -syscall ZwAllocateUuids(ptr ptr ptr ptr) NtAllocateUuids
@ stdcall -private -syscall ZwAllocateVirtualMemory(long ptr long ptr long long) NtAllocateVirtualMemory
@ stdcall -private -syscall ZwAreMappedFilesTheSame(ptr ptr) NtAreMappedFilesTheSame
@ stdcall -private -syscall ZwAssignProcessToJobObject(long long) NtAssignProcessToJobObject
@ -1299,7 +1299,7 @@
# @ stub ZwQueryPortInformationProcess
# @ stub ZwQueryQuotaInformationFile
@ stdcall -private -syscall ZwQuerySection(long long ptr long ptr) NtQuerySection
@ stdcall -private ZwQuerySecurityObject(long long ptr long ptr) NtQuerySecurityObject
@ stdcall -private -syscall ZwQuerySecurityObject(long long ptr long ptr) NtQuerySecurityObject
@ stdcall -private -syscall ZwQuerySemaphore(long long ptr long ptr) NtQuerySemaphore
@ stdcall -private -syscall ZwQuerySymbolicLinkObject(long ptr ptr) NtQuerySymbolicLinkObject
@ stdcall -private -syscall ZwQuerySystemEnvironmentValue(ptr ptr long ptr) NtQuerySystemEnvironmentValue
@ -1376,7 +1376,7 @@
@ stub ZwSetLowWaitHighThread
@ stdcall -private -syscall ZwSetPowerRequest(long long) NtSetPowerRequest
# @ stub ZwSetQuotaInformationFile
@ stdcall -private ZwSetSecurityObject(long long ptr) NtSetSecurityObject
@ stdcall -private -syscall ZwSetSecurityObject(long long ptr) NtSetSecurityObject
@ stub ZwSetSystemEnvironmentValue
# @ stub ZwSetSystemEnvironmentValueEx
@ stdcall -private -syscall ZwSetSystemInformation(long ptr long) NtSetSystemInformation

View File

@ -32,101 +32,11 @@
#include "wine/server.h"
#include "wine/exception.h"
WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
/*
* Generic object functions
*/
/******************************************************************************
* NtQuerySecurityObject [NTDLL.@]
*
* An ntdll analogue to GetKernelObjectSecurity().
*
*/
NTSTATUS WINAPI
NtQuerySecurityObject(
IN HANDLE Object,
IN SECURITY_INFORMATION RequestedInformation,
OUT PSECURITY_DESCRIPTOR pSecurityDescriptor,
IN ULONG Length,
OUT PULONG ResultLength)
{
PISECURITY_DESCRIPTOR_RELATIVE psd = pSecurityDescriptor;
NTSTATUS status;
unsigned int buffer_size = 512;
BOOLEAN need_more_memory;
TRACE("(%p,0x%08x,%p,0x%08x,%p)\n",
Object, RequestedInformation, pSecurityDescriptor, Length, ResultLength);
do
{
char *buffer = RtlAllocateHeap(GetProcessHeap(), 0, buffer_size);
if (!buffer)
return STATUS_NO_MEMORY;
need_more_memory = FALSE;
SERVER_START_REQ( get_security_object )
{
req->handle = wine_server_obj_handle( Object );
req->security_info = RequestedInformation;
wine_server_set_reply( req, buffer, buffer_size );
status = wine_server_call( req );
if (status == STATUS_SUCCESS)
{
struct security_descriptor *sd = (struct security_descriptor *)buffer;
if (reply->sd_len)
{
*ResultLength = sizeof(SECURITY_DESCRIPTOR_RELATIVE) +
sd->owner_len + sd->group_len + sd->sacl_len + sd->dacl_len;
if (Length >= *ResultLength)
{
psd->Revision = SECURITY_DESCRIPTOR_REVISION;
psd->Sbz1 = 0;
psd->Control = sd->control | SE_SELF_RELATIVE;
psd->Owner = sd->owner_len ? sizeof(SECURITY_DESCRIPTOR_RELATIVE) : 0;
psd->Group = sd->group_len ? sizeof(SECURITY_DESCRIPTOR_RELATIVE) + sd->owner_len : 0;
psd->Sacl = sd->sacl_len ? sizeof(SECURITY_DESCRIPTOR_RELATIVE) + sd->owner_len + sd->group_len : 0;
psd->Dacl = sd->dacl_len ? sizeof(SECURITY_DESCRIPTOR_RELATIVE) + sd->owner_len + sd->group_len + sd->sacl_len : 0;
/* owner, group, sacl and dacl are the same type as in the server
* and in the same order so we copy the memory in one block */
memcpy((char *)pSecurityDescriptor + sizeof(SECURITY_DESCRIPTOR_RELATIVE),
buffer + sizeof(struct security_descriptor),
sd->owner_len + sd->group_len + sd->sacl_len + sd->dacl_len);
}
else
status = STATUS_BUFFER_TOO_SMALL;
}
else
{
*ResultLength = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
if (Length >= *ResultLength)
{
memset(psd, 0, sizeof(*psd));
psd->Revision = SECURITY_DESCRIPTOR_REVISION;
psd->Control = SE_SELF_RELATIVE;
}
else
status = STATUS_BUFFER_TOO_SMALL;
}
}
else if (status == STATUS_BUFFER_TOO_SMALL)
{
buffer_size = reply->sd_len;
need_more_memory = TRUE;
}
}
SERVER_END_REQ;
RtlFreeHeap(GetProcessHeap(), 0, buffer);
} while (need_more_memory);
return status;
}
static LONG WINAPI invalid_handle_exception_handler( EXCEPTION_POINTERS *eptr )
{
EXCEPTION_RECORD *rec = eptr->ExceptionRecord;
@ -178,12 +88,3 @@ NTSTATUS WINAPI NtClose( HANDLE Handle )
{
return close_handle( Handle );
}
/******************************************************************************
* NtAllocateUuids [NTDLL.@]
*/
NTSTATUS WINAPI NtAllocateUuids( ULARGE_INTEGER *time, ULONG *delta, ULONG *sequence, UCHAR *seed )
{
FIXME("(%p,%p,%p,%p), stub.\n", time, delta, sequence, seed);
return STATUS_SUCCESS;
}

View File

@ -1603,192 +1603,6 @@ RtlImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
return Status;
}
/******************************************************************************
* NtAccessCheck [NTDLL.@]
* ZwAccessCheck [NTDLL.@]
*
* Checks that a user represented by a token is allowed to access an object
* represented by a security descriptor.
*
* PARAMS
* SecurityDescriptor [I] The security descriptor of the object to check.
* ClientToken [I] Token of the user accessing the object.
* DesiredAccess [I] The desired access to the object.
* GenericMapping [I] Mapping used to transform access rights in the SD to their specific forms.
* PrivilegeSet [I/O] Privileges used during the access check.
* ReturnLength [O] Number of bytes stored into PrivilegeSet.
* GrantedAccess [O] The actual access rights granted.
* AccessStatus [O] The status of the access check.
*
* RETURNS
* NTSTATUS code.
*
* NOTES
* DesiredAccess may be MAXIMUM_ALLOWED, in which case the function determines
* the maximum access rights allowed by the SD and returns them in
* GrantedAccess.
* The SecurityDescriptor must have a valid owner and groups present,
* otherwise the function will fail.
*/
NTSTATUS WINAPI
NtAccessCheck(
PSECURITY_DESCRIPTOR SecurityDescriptor,
HANDLE ClientToken,
ACCESS_MASK DesiredAccess,
PGENERIC_MAPPING GenericMapping,
PPRIVILEGE_SET PrivilegeSet,
PULONG ReturnLength,
PULONG GrantedAccess,
NTSTATUS *AccessStatus)
{
NTSTATUS status;
TRACE("(%p, %p, %08x, %p, %p, %p, %p, %p)\n",
SecurityDescriptor, ClientToken, DesiredAccess, GenericMapping,
PrivilegeSet, ReturnLength, GrantedAccess, AccessStatus);
if (!PrivilegeSet || !ReturnLength)
return STATUS_ACCESS_VIOLATION;
SERVER_START_REQ( access_check )
{
struct security_descriptor sd;
PSID owner;
PSID group;
PACL sacl;
PACL dacl;
BOOLEAN defaulted, present;
DWORD revision;
SECURITY_DESCRIPTOR_CONTROL control;
req->handle = wine_server_obj_handle( ClientToken );
req->desired_access = DesiredAccess;
req->mapping_read = GenericMapping->GenericRead;
req->mapping_write = GenericMapping->GenericWrite;
req->mapping_execute = GenericMapping->GenericExecute;
req->mapping_all = GenericMapping->GenericAll;
/* marshal security descriptor */
RtlGetControlSecurityDescriptor( SecurityDescriptor, &control, &revision );
sd.control = control & ~SE_SELF_RELATIVE;
RtlGetOwnerSecurityDescriptor( SecurityDescriptor, &owner, &defaulted );
sd.owner_len = RtlLengthSid( owner );
RtlGetGroupSecurityDescriptor( SecurityDescriptor, &group, &defaulted );
sd.group_len = RtlLengthSid( group );
RtlGetSaclSecurityDescriptor( SecurityDescriptor, &present, &sacl, &defaulted );
sd.sacl_len = ((present && sacl) ? acl_bytesInUse(sacl) : 0);
RtlGetDaclSecurityDescriptor( SecurityDescriptor, &present, &dacl, &defaulted );
sd.dacl_len = ((present && dacl) ? acl_bytesInUse(dacl) : 0);
wine_server_add_data( req, &sd, sizeof(sd) );
wine_server_add_data( req, owner, sd.owner_len );
wine_server_add_data( req, group, sd.group_len );
wine_server_add_data( req, sacl, sd.sacl_len );
wine_server_add_data( req, dacl, sd.dacl_len );
wine_server_set_reply( req, PrivilegeSet->Privilege, *ReturnLength - FIELD_OFFSET( PRIVILEGE_SET, Privilege ) );
status = wine_server_call( req );
*ReturnLength = FIELD_OFFSET( PRIVILEGE_SET, Privilege ) + reply->privileges_len;
PrivilegeSet->PrivilegeCount = reply->privileges_len / sizeof(LUID_AND_ATTRIBUTES);
if (status == STATUS_SUCCESS)
{
*AccessStatus = reply->access_status;
*GrantedAccess = reply->access_granted;
}
}
SERVER_END_REQ;
return status;
}
/******************************************************************************
* NtSetSecurityObject [NTDLL.@]
* ZwSetSecurityObject [NTDLL.@]
*
* Sets specified parts of the object's security descriptor.
*
* PARAMS
* Handle [I] Handle to the object to change security descriptor of.
* SecurityInformation [I] Specifies which parts of the security descriptor to set.
* SecurityDescriptor [I] New parts of a security descriptor for the object.
*
* RETURNS
* NTSTATUS code.
*
*/
NTSTATUS WINAPI NtSetSecurityObject(HANDLE Handle,
SECURITY_INFORMATION SecurityInformation,
PSECURITY_DESCRIPTOR SecurityDescriptor)
{
NTSTATUS status;
struct security_descriptor sd;
PACL dacl = NULL, sacl = NULL;
PSID owner = NULL, group = NULL;
BOOLEAN defaulted, present;
DWORD revision;
SECURITY_DESCRIPTOR_CONTROL control;
TRACE("%p 0x%08x %p\n", Handle, SecurityInformation, SecurityDescriptor);
if (!SecurityDescriptor) return STATUS_ACCESS_VIOLATION;
memset( &sd, 0, sizeof(sd) );
status = RtlGetControlSecurityDescriptor( SecurityDescriptor, &control, &revision );
if (status != STATUS_SUCCESS) return status;
sd.control = control & ~SE_SELF_RELATIVE;
if (SecurityInformation & OWNER_SECURITY_INFORMATION)
{
status = RtlGetOwnerSecurityDescriptor( SecurityDescriptor, &owner, &defaulted );
if (status != STATUS_SUCCESS) return status;
if (!(sd.owner_len = RtlLengthSid( owner )))
return STATUS_INVALID_SECURITY_DESCR;
}
if (SecurityInformation & GROUP_SECURITY_INFORMATION)
{
status = RtlGetGroupSecurityDescriptor( SecurityDescriptor, &group, &defaulted );
if (status != STATUS_SUCCESS) return status;
if (!(sd.group_len = RtlLengthSid( group )))
return STATUS_INVALID_SECURITY_DESCR;
}
if (SecurityInformation & SACL_SECURITY_INFORMATION ||
SecurityInformation & LABEL_SECURITY_INFORMATION)
{
status = RtlGetSaclSecurityDescriptor( SecurityDescriptor, &present, &sacl, &defaulted );
if (status != STATUS_SUCCESS) return status;
sd.sacl_len = (sacl && present) ? acl_bytesInUse(sacl) : 0;
sd.control |= SE_SACL_PRESENT;
}
if (SecurityInformation & DACL_SECURITY_INFORMATION)
{
status = RtlGetDaclSecurityDescriptor( SecurityDescriptor, &present, &dacl, &defaulted );
if (status != STATUS_SUCCESS) return status;
sd.dacl_len = (dacl && present) ? acl_bytesInUse(dacl) : 0;
sd.control |= SE_DACL_PRESENT;
}
SERVER_START_REQ( set_security_object )
{
req->handle = wine_server_obj_handle( Handle );
req->security_info = SecurityInformation;
wine_server_add_data( req, &sd, sizeof(sd) );
wine_server_add_data( req, owner, sd.owner_len );
wine_server_add_data( req, group, sd.group_len );
wine_server_add_data( req, sacl, sd.sacl_len );
wine_server_add_data( req, dacl, sd.dacl_len );
status = wine_server_call( req );
}
SERVER_END_REQ;
return status;
}
/******************************************************************************
* RtlConvertSidToUnicodeString (NTDLL.@)

View File

@ -633,3 +633,200 @@ NTSTATUS WINAPI NtImpersonateAnonymousToken( HANDLE thread )
FIXME( "(%p): stub\n", thread );
return STATUS_NOT_IMPLEMENTED;
}
/***********************************************************************
* NtAccessCheck (NTDLL.@)
*/
NTSTATUS WINAPI NtAccessCheck( PSECURITY_DESCRIPTOR descr, HANDLE token, ACCESS_MASK access,
GENERIC_MAPPING *mapping, PRIVILEGE_SET *privs, ULONG *retlen,
ULONG *access_granted, NTSTATUS *access_status)
{
struct object_attributes *objattr;
data_size_t len;
OBJECT_ATTRIBUTES attr;
NTSTATUS status;
TRACE( "(%p, %p, %08x, %p, %p, %p, %p, %p)\n",
descr, token, access, mapping, privs, retlen, access_granted, access_status );
if (!privs || !retlen) return STATUS_ACCESS_VIOLATION;
/* reuse the object attribute SD marshalling */
InitializeObjectAttributes( &attr, NULL, 0, 0, descr );
if ((status = alloc_object_attributes( &attr, &objattr, &len ))) return status;
SERVER_START_REQ( access_check )
{
req->handle = wine_server_obj_handle( token );
req->desired_access = access;
req->mapping_read = mapping->GenericRead;
req->mapping_write = mapping->GenericWrite;
req->mapping_execute = mapping->GenericExecute;
req->mapping_all = mapping->GenericAll;
wine_server_add_data( req, objattr + 1, objattr->sd_len );
wine_server_set_reply( req, privs->Privilege, *retlen - offsetof( PRIVILEGE_SET, Privilege ) );
status = wine_server_call( req );
*retlen = offsetof( PRIVILEGE_SET, Privilege ) + reply->privileges_len;
privs->PrivilegeCount = reply->privileges_len / sizeof(LUID_AND_ATTRIBUTES);
if (status == STATUS_SUCCESS)
{
*access_status = reply->access_status;
*access_granted = reply->access_granted;
}
}
SERVER_END_REQ;
free( objattr );
return status;
}
/***********************************************************************
* NtAccessCheckAndAuditAlarm (NTDLL.@)
*/
NTSTATUS WINAPI NtAccessCheckAndAuditAlarm( UNICODE_STRING *subsystem, HANDLE handle,
UNICODE_STRING *typename, UNICODE_STRING *objectname,
PSECURITY_DESCRIPTOR descr, ACCESS_MASK access,
GENERIC_MAPPING *mapping, BOOLEAN creation,
ACCESS_MASK *access_granted, BOOLEAN *access_status,
BOOLEAN *onclose )
{
FIXME( "(%s, %p, %s, %p, 0x%08x, %p, %d, %p, %p, %p), stub\n",
debugstr_us(subsystem), handle, debugstr_us(typename), descr, access,
mapping, creation, access_granted, access_status, onclose );
return STATUS_NOT_IMPLEMENTED;
}
/***********************************************************************
* NtQuerySecurityObject (NTDLL.@)
*/
NTSTATUS WINAPI NtQuerySecurityObject( HANDLE handle, SECURITY_INFORMATION info,
PSECURITY_DESCRIPTOR descr, ULONG length, ULONG *retlen )
{
SECURITY_DESCRIPTOR_RELATIVE *psd = descr;
NTSTATUS status;
void *buffer;
unsigned int buffer_size = 512;
TRACE( "(%p,0x%08x,%p,0x%08x,%p)\n", handle, info, descr, length, retlen );
for (;;)
{
if (!(buffer = malloc( buffer_size ))) return STATUS_NO_MEMORY;
SERVER_START_REQ( get_security_object )
{
req->handle = wine_server_obj_handle( handle );
req->security_info = info;
wine_server_set_reply( req, buffer, buffer_size );
status = wine_server_call( req );
buffer_size = reply->sd_len;
}
SERVER_END_REQ;
if (status == STATUS_BUFFER_TOO_SMALL)
{
free( buffer );
continue;
}
if (status == STATUS_SUCCESS)
{
struct security_descriptor *sd = buffer;
if (!buffer_size) memset( sd, 0, sizeof(*sd) );
*retlen = sizeof(*psd) + sd->owner_len + sd->group_len + sd->sacl_len + sd->dacl_len;
if (length >= *retlen)
{
DWORD len = sizeof(*psd);
memset( psd, 0, len );
psd->Revision = SECURITY_DESCRIPTOR_REVISION;
psd->Control = sd->control | SE_SELF_RELATIVE;
if (sd->owner_len) { psd->Owner = len; len += sd->owner_len; }
if (sd->group_len) { psd->Group = len; len += sd->group_len; }
if (sd->sacl_len) { psd->Sacl = len; len += sd->sacl_len; }
if (sd->dacl_len) { psd->Dacl = len; len += sd->dacl_len; }
/* owner, group, sacl and dacl are the same type as in the server
* and in the same order so we copy the memory in one block */
memcpy( psd + 1, sd + 1, len - sizeof(*psd) );
}
else status = STATUS_BUFFER_TOO_SMALL;
}
free( buffer );
return status;
}
}
/***********************************************************************
* NtSetSecurityObject (NTDLL.@)
*/
NTSTATUS WINAPI NtSetSecurityObject( HANDLE handle, SECURITY_INFORMATION info, PSECURITY_DESCRIPTOR descr )
{
struct object_attributes *objattr;
struct security_descriptor *sd;
data_size_t len;
OBJECT_ATTRIBUTES attr;
NTSTATUS status;
TRACE( "%p 0x%08x %p\n", handle, info, descr );
if (!descr) return STATUS_ACCESS_VIOLATION;
/* reuse the object attribute SD marshalling */
InitializeObjectAttributes( &attr, NULL, 0, 0, descr );
if ((status = alloc_object_attributes( &attr, &objattr, &len ))) return status;
sd = (struct security_descriptor *)(objattr + 1);
if (info & OWNER_SECURITY_INFORMATION && !sd->owner_len) return STATUS_INVALID_SECURITY_DESCR;
if (info & GROUP_SECURITY_INFORMATION && !sd->group_len) return STATUS_INVALID_SECURITY_DESCR;
if (info & (SACL_SECURITY_INFORMATION | LABEL_SECURITY_INFORMATION)) sd->control |= SE_SACL_PRESENT;
if (info & DACL_SECURITY_INFORMATION) sd->control |= SE_DACL_PRESENT;
SERVER_START_REQ( set_security_object )
{
req->handle = wine_server_obj_handle( handle );
req->security_info = info;
wine_server_add_data( req, sd, objattr->sd_len );
status = wine_server_call( req );
}
SERVER_END_REQ;
free( objattr );
return status;
}
/***********************************************************************
* NtAllocateLocallyUniqueId (NTDLL.@)
*/
NTSTATUS WINAPI NtAllocateLocallyUniqueId( LUID *luid )
{
NTSTATUS status;
TRACE( "%p\n", luid );
if (!luid) return STATUS_ACCESS_VIOLATION;
SERVER_START_REQ( allocate_locally_unique_id )
{
status = wine_server_call( req );
if (!status)
{
luid->LowPart = reply->luid.low_part;
luid->HighPart = reply->luid.high_part;
}
}
SERVER_END_REQ;
return status;
}
/***********************************************************************
* NtAllocateUuids (NTDLL.@)
*/
NTSTATUS WINAPI NtAllocateUuids( ULARGE_INTEGER *time, ULONG *delta, ULONG *sequence, UCHAR *seed )
{
FIXME( "(%p,%p,%p,%p), stub.\n", time, delta, sequence, seed );
return STATUS_SUCCESS;
}