server: Define a server-side structure for ACE.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2022-01-25 12:21:14 +01:00
parent c36f81fa75
commit 841b8862fb
6 changed files with 143 additions and 253 deletions

View File

@ -309,25 +309,21 @@ static struct fd *file_get_fd( struct object *obj )
struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID *group )
{
struct security_descriptor *sd;
unsigned char flags;
size_t dacl_size;
ACE_HEADER *current_ace;
ACCESS_ALLOWED_ACE *aaa;
struct ace *ace;
struct acl *dacl;
SID *sid;
char *ptr;
const SID *world_sid = security_world_sid;
const SID *local_system_sid = security_local_system_sid;
dacl_size = sizeof(*dacl) + FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) +
security_sid_len( local_system_sid );
if (mode & S_IRWXU)
dacl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + security_sid_len( user );
dacl_size = sizeof(*dacl) + sizeof(*ace) + security_sid_len( local_system_sid );
if (mode & S_IRWXU) dacl_size += sizeof(*ace) + security_sid_len( user );
if ((!(mode & S_IRUSR) && (mode & (S_IRGRP|S_IROTH))) ||
(!(mode & S_IWUSR) && (mode & (S_IWGRP|S_IWOTH))) ||
(!(mode & S_IXUSR) && (mode & (S_IXGRP|S_IXOTH))))
dacl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + security_sid_len( user );
if (mode & S_IRWXO)
dacl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + security_sid_len( world_sid );
dacl_size += sizeof(*ace) + security_sid_len( user );
if (mode & S_IRWXO) dacl_size += sizeof(*ace) + security_sid_len( world_sid );
sd = mem_alloc( sizeof(struct security_descriptor) +
security_sid_len( user ) + security_sid_len( group ) +
@ -359,66 +355,37 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID
dacl->count++;
if (mode & S_IRWXO) dacl->count++;
flags = (mode & S_IFDIR) ? OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE : 0;
/* always give FILE_ALL_ACCESS for Local System */
aaa = (ACCESS_ALLOWED_ACE *)(dacl + 1);
current_ace = &aaa->Header;
aaa->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
aaa->Header.AceFlags = (mode & S_IFDIR) ? OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE : 0;
aaa->Header.AceSize = FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + security_sid_len( local_system_sid );
aaa->Mask = FILE_ALL_ACCESS;
sid = (SID *)&aaa->SidStart;
memcpy( sid, local_system_sid, security_sid_len( local_system_sid ));
ace = set_ace( (struct ace *)(dacl + 1), local_system_sid,
ACCESS_ALLOWED_ACE_TYPE, flags, FILE_ALL_ACCESS );
if (mode & S_IRWXU)
{
/* appropriate access rights for the user */
aaa = (ACCESS_ALLOWED_ACE *)ace_next( current_ace );
current_ace = &aaa->Header;
aaa->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
aaa->Header.AceFlags = (mode & S_IFDIR) ? OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE : 0;
aaa->Header.AceSize = FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + security_sid_len( user );
aaa->Mask = WRITE_DAC | WRITE_OWNER;
if (mode & S_IRUSR)
aaa->Mask |= FILE_GENERIC_READ | FILE_GENERIC_EXECUTE;
if (mode & S_IWUSR)
aaa->Mask |= FILE_GENERIC_WRITE | DELETE | FILE_DELETE_CHILD;
sid = (SID *)&aaa->SidStart;
memcpy( sid, user, security_sid_len( user ));
ace = set_ace( ace_next( ace ), user, ACCESS_ALLOWED_ACE_TYPE, flags, WRITE_DAC | WRITE_OWNER );
if (mode & S_IRUSR) ace->mask |= FILE_GENERIC_READ | FILE_GENERIC_EXECUTE;
if (mode & S_IWUSR) ace->mask |= FILE_GENERIC_WRITE | DELETE | FILE_DELETE_CHILD;
}
if ((!(mode & S_IRUSR) && (mode & (S_IRGRP|S_IROTH))) ||
(!(mode & S_IWUSR) && (mode & (S_IWGRP|S_IWOTH))) ||
(!(mode & S_IXUSR) && (mode & (S_IXGRP|S_IXOTH))))
{
/* deny just in case the user is a member of the group */
ACCESS_DENIED_ACE *ada = (ACCESS_DENIED_ACE *)ace_next( current_ace );
current_ace = &ada->Header;
ada->Header.AceType = ACCESS_DENIED_ACE_TYPE;
ada->Header.AceFlags = (mode & S_IFDIR) ? OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE : 0;
ada->Header.AceSize = FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + security_sid_len( user );
ada->Mask = 0;
ace = set_ace( ace_next( ace ), user, ACCESS_DENIED_ACE_TYPE, flags, 0 );
if (!(mode & S_IRUSR) && (mode & (S_IRGRP|S_IROTH)))
ada->Mask |= FILE_GENERIC_READ | FILE_GENERIC_EXECUTE;
ace->mask |= FILE_GENERIC_READ | FILE_GENERIC_EXECUTE;
if (!(mode & S_IWUSR) && (mode & (S_IWGRP|S_IROTH)))
ada->Mask |= FILE_GENERIC_WRITE | DELETE | FILE_DELETE_CHILD;
ada->Mask &= ~STANDARD_RIGHTS_ALL; /* never deny standard rights */
sid = (SID *)&ada->SidStart;
memcpy( sid, user, security_sid_len( user ));
ace->mask |= FILE_GENERIC_WRITE | DELETE | FILE_DELETE_CHILD;
ace->mask &= ~STANDARD_RIGHTS_ALL; /* never deny standard rights */
}
if (mode & S_IRWXO)
{
/* appropriate access rights for Everyone */
aaa = (ACCESS_ALLOWED_ACE *)ace_next( current_ace );
current_ace = &aaa->Header;
aaa->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
aaa->Header.AceFlags = (mode & S_IFDIR) ? OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE : 0;
aaa->Header.AceSize = FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + security_sid_len( world_sid );
aaa->Mask = 0;
if (mode & S_IROTH)
aaa->Mask |= FILE_GENERIC_READ | FILE_GENERIC_EXECUTE;
if (mode & S_IWOTH)
aaa->Mask |= FILE_GENERIC_WRITE | DELETE | FILE_DELETE_CHILD;
sid = (SID *)&aaa->SidStart;
memcpy( sid, world_sid, security_sid_len( world_sid ));
ace = set_ace( ace_next( ace ), world_sid, ACCESS_ALLOWED_ACE_TYPE, flags, 0 );
if (mode & S_IROTH) ace->mask |= FILE_GENERIC_READ | FILE_GENERIC_EXECUTE;
if (mode & S_IWOTH) ace->mask |= FILE_GENERIC_WRITE | DELETE | FILE_DELETE_CHILD;
}
return sd;
@ -473,24 +440,22 @@ mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner )
mode_t mode;
int present;
const struct acl *dacl = sd_get_dacl( sd, &present );
if (present && dacl)
{
const ACE_HEADER *ace = (const ACE_HEADER *)(dacl + 1);
ULONG i;
const struct ace *ace = (const struct ace *)(dacl + 1);
unsigned int i;
for (i = 0; i < dacl->count; i++, ace = ace_next( ace ))
{
const ACCESS_ALLOWED_ACE *aa_ace;
const ACCESS_DENIED_ACE *ad_ace;
const SID *sid;
const SID *sid = (const SID *)(ace + 1);
if (ace->AceFlags & INHERIT_ONLY_ACE) continue;
if (ace->flags & INHERIT_ONLY_ACE) continue;
switch (ace->AceType)
mode = file_access_to_mode( ace->mask );
switch (ace->type)
{
case ACCESS_DENIED_ACE_TYPE:
ad_ace = (const ACCESS_DENIED_ACE *)ace;
sid = (const SID *)&ad_ace->SidStart;
mode = file_access_to_mode( ad_ace->Mask );
if (security_equal_sid( sid, security_world_sid ))
{
bits_to_set &= ~((mode << 6) | (mode << 3) | mode); /* all */
@ -506,9 +471,6 @@ mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner )
}
break;
case ACCESS_ALLOWED_ACE_TYPE:
aa_ace = (const ACCESS_ALLOWED_ACE *)ace;
sid = (const SID *)&aa_ace->SidStart;
mode = file_access_to_mode( aa_ace->Mask );
if (security_equal_sid( sid, security_world_sid ))
{
mode = (mode << 6) | (mode << 3) | mode; /* all */

View File

@ -823,12 +823,11 @@ static struct security_descriptor *process_get_sd( struct object *obj )
if (!process_default_sd)
{
struct ace *ace;
struct acl *dacl;
size_t users_sid_len = security_sid_len( security_domain_users_sid );
size_t admins_sid_len = security_sid_len( security_builtin_admins_sid );
size_t dacl_len = sizeof(struct acl) + 2 * offsetof( ACCESS_ALLOWED_ACE, SidStart )
+ users_sid_len + admins_sid_len;
ACCESS_ALLOWED_ACE *aaa;
struct acl *dacl;
size_t dacl_len = sizeof(*dacl) + 2 * sizeof(*ace) + users_sid_len + admins_sid_len;
process_default_sd = mem_alloc( sizeof(*process_default_sd) + admins_sid_len + users_sid_len
+ dacl_len );
@ -846,18 +845,9 @@ static struct security_descriptor *process_get_sd( struct object *obj )
dacl->size = dacl_len;
dacl->count = 2;
dacl->pad2 = 0;
aaa = (ACCESS_ALLOWED_ACE *)(dacl + 1);
aaa->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
aaa->Header.AceFlags = INHERIT_ONLY_ACE | CONTAINER_INHERIT_ACE;
aaa->Header.AceSize = offsetof( ACCESS_ALLOWED_ACE, SidStart ) + users_sid_len;
aaa->Mask = GENERIC_READ;
memcpy( &aaa->SidStart, security_domain_users_sid, users_sid_len );
aaa = (ACCESS_ALLOWED_ACE *)((char *)aaa + aaa->Header.AceSize);
aaa->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
aaa->Header.AceFlags = 0;
aaa->Header.AceSize = offsetof( ACCESS_ALLOWED_ACE, SidStart ) + admins_sid_len;
aaa->Mask = PROCESS_ALL_ACCESS;
memcpy( &aaa->SidStart, security_builtin_admins_sid, admins_sid_len );
ace = set_ace( ace_first( dacl ), security_domain_users_sid, ACCESS_ALLOWED_ACE_TYPE,
INHERIT_ONLY_ACE | CONTAINER_INHERIT_ACE, GENERIC_READ );
set_ace( ace_next( ace ), security_builtin_admins_sid, ACCESS_ALLOWED_ACE_TYPE, 0, PROCESS_ALL_ACCESS );
}
return process_default_sd;
}

View File

@ -370,11 +370,10 @@ static struct security_descriptor *key_get_sd( struct object *obj )
if (!key_default_sd)
{
struct acl *dacl;
struct ace *ace;
size_t users_sid_len = security_sid_len( security_builtin_users_sid );
size_t admins_sid_len = security_sid_len( security_builtin_admins_sid );
size_t dacl_len = sizeof(*dacl) + 2 * offsetof( ACCESS_ALLOWED_ACE, SidStart )
+ users_sid_len + admins_sid_len;
ACCESS_ALLOWED_ACE *aaa;
size_t dacl_len = sizeof(*dacl) + 2 * sizeof(*ace) + users_sid_len + admins_sid_len;
key_default_sd = mem_alloc( sizeof(*key_default_sd) + 2 * admins_sid_len + dacl_len );
key_default_sd->control = SE_DACL_PRESENT;
@ -391,18 +390,9 @@ static struct security_descriptor *key_get_sd( struct object *obj )
dacl->size = dacl_len;
dacl->count = 2;
dacl->pad2 = 0;
aaa = (ACCESS_ALLOWED_ACE *)(dacl + 1);
aaa->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
aaa->Header.AceFlags = INHERIT_ONLY_ACE | CONTAINER_INHERIT_ACE;
aaa->Header.AceSize = offsetof( ACCESS_ALLOWED_ACE, SidStart ) + users_sid_len;
aaa->Mask = GENERIC_READ;
memcpy( &aaa->SidStart, security_builtin_users_sid, users_sid_len );
aaa = (ACCESS_ALLOWED_ACE *)((char *)aaa + aaa->Header.AceSize);
aaa->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
aaa->Header.AceFlags = 0;
aaa->Header.AceSize = offsetof( ACCESS_ALLOWED_ACE, SidStart ) + admins_sid_len;
aaa->Mask = KEY_ALL_ACCESS;
memcpy( &aaa->SidStart, security_builtin_admins_sid, admins_sid_len );
ace = set_ace( ace_first( dacl ), security_builtin_users_sid, ACCESS_ALLOWED_ACE_TYPE,
INHERIT_ONLY_ACE | CONTAINER_INHERIT_ACE, GENERIC_READ );
set_ace( ace_next( ace ), security_builtin_admins_sid, ACCESS_ALLOWED_ACE_TYPE, 0, KEY_ALL_ACCESS );
}
return key_default_sd;
}

View File

@ -52,6 +52,13 @@ extern const PSID security_builtin_admins_sid;
extern const PSID security_domain_users_sid;
extern const PSID security_high_label_sid;
struct ace
{
unsigned char type;
unsigned char flags;
unsigned short size;
unsigned int mask;
};
/* token functions */
@ -71,9 +78,14 @@ extern const SID *token_get_primary_group( struct token *token );
extern unsigned int token_get_session_id( struct token *token );
extern int token_sid_present( struct token *token, const SID *sid, int deny);
static inline const ACE_HEADER *ace_next( const ACE_HEADER *ace )
static inline struct ace *ace_first( const struct acl *acl )
{
return (const ACE_HEADER *)((const char *)ace + ace->AceSize);
return (struct ace *)(acl + 1);
}
static inline struct ace *ace_next( const struct ace *ace )
{
return (struct ace *)((char *)ace + ace->size);
}
static inline size_t security_sid_len( const SID *sid )
@ -87,6 +99,22 @@ static inline int security_equal_sid( const SID *sid1, const SID *sid2 )
!memcmp( sid1, sid2, security_sid_len( sid1 )));
}
static inline int sid_valid_size( const SID *sid, data_size_t size )
{
return (size >= offsetof( SID, SubAuthority[0] ) && size >= security_sid_len( sid ));
}
static inline struct ace *set_ace( struct ace *ace, const SID *sid, unsigned char type,
unsigned char flags, unsigned int mask )
{
ace->type = type;
ace->flags = flags;
ace->size = sizeof(*ace) + security_sid_len( sid );
ace->mask = mask;
memcpy( ace + 1, sid, security_sid_len( sid ));
return ace;
}
extern void security_set_thread_token( struct thread *thread, obj_handle_t handle );
extern const SID *security_unix_uid_to_sid( uid_t uid );
extern int check_object_access( struct token *token, struct object *obj, unsigned int *access );

View File

@ -238,52 +238,29 @@ const SID *security_unix_uid_to_sid( uid_t uid )
static int acl_is_valid( const struct acl *acl, data_size_t size )
{
ULONG i;
const ACE_HEADER *ace;
const struct ace *ace;
if (size < sizeof(*acl)) return FALSE;
size = min(size, MAX_ACL_LEN);
size -= sizeof(*acl);
ace = (const ACE_HEADER *)(acl + 1);
for (i = 0; i < acl->count; i++)
for (i = 0, ace = ace_first( acl ); i < acl->count; i++, ace = ace_next( ace ))
{
const SID *sid;
data_size_t sid_size;
if (size < sizeof(ACE_HEADER))
return FALSE;
if (size < ace->AceSize)
return FALSE;
size -= ace->AceSize;
switch (ace->AceType)
if (size < sizeof(*ace) || size < ace->size) return FALSE;
size -= ace->size;
switch (ace->type)
{
case ACCESS_DENIED_ACE_TYPE:
sid = (const SID *)&((const ACCESS_DENIED_ACE *)ace)->SidStart;
sid_size = ace->AceSize - FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart);
break;
case ACCESS_ALLOWED_ACE_TYPE:
sid = (const SID *)&((const ACCESS_ALLOWED_ACE *)ace)->SidStart;
sid_size = ace->AceSize - FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart);
break;
case SYSTEM_AUDIT_ACE_TYPE:
sid = (const SID *)&((const SYSTEM_AUDIT_ACE *)ace)->SidStart;
sid_size = ace->AceSize - FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart);
break;
case SYSTEM_ALARM_ACE_TYPE:
sid = (const SID *)&((const SYSTEM_ALARM_ACE *)ace)->SidStart;
sid_size = ace->AceSize - FIELD_OFFSET(SYSTEM_ALARM_ACE, SidStart);
break;
case SYSTEM_MANDATORY_LABEL_ACE_TYPE:
sid = (const SID *)&((const SYSTEM_MANDATORY_LABEL_ACE *)ace)->SidStart;
sid_size = ace->AceSize - FIELD_OFFSET(SYSTEM_MANDATORY_LABEL_ACE, SidStart);
break;
default:
return FALSE;
}
if (sid_size < FIELD_OFFSET(SID, SubAuthority[0]) || sid_size < security_sid_len( sid ))
return FALSE;
ace = ace_next( ace );
if (!sid_valid_size( (const SID *)(ace + 1), ace->size - sizeof(*ace) )) return FALSE;
}
return TRUE;
}
@ -358,17 +335,16 @@ int sd_is_valid( const struct security_descriptor *sd, data_size_t size )
struct acl *extract_security_labels( const struct acl *sacl )
{
size_t size = sizeof(*sacl);
const ACE_HEADER *ace;
ACE_HEADER *label_ace;
const struct ace *ace;
struct ace *label_ace;
unsigned int i, count = 0;
struct acl *label_acl;
ace = (const ACE_HEADER *)(sacl + 1);
for (i = 0; i < sacl->count; i++, ace = ace_next( ace ))
for (i = 0, ace = ace_first( sacl ); i < sacl->count; i++, ace = ace_next( ace ))
{
if (ace->AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE)
if (ace->type == SYSTEM_MANDATORY_LABEL_ACE_TYPE)
{
size += ace->AceSize;
size += ace->size;
count++;
}
}
@ -381,15 +357,14 @@ struct acl *extract_security_labels( const struct acl *sacl )
label_acl->size = size;
label_acl->count = count;
label_acl->pad2 = 0;
label_ace = (ACE_HEADER *)(label_acl + 1);
ace = (const ACE_HEADER *)(sacl + 1);
for (i = 0; i < sacl->count; i++, ace = ace_next( ace ))
label_ace = ace_first( label_acl );
for (i = 0, ace = ace_first( sacl ); i < sacl->count; i++, ace = ace_next( ace ))
{
if (ace->AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE)
if (ace->type == SYSTEM_MANDATORY_LABEL_ACE_TYPE)
{
memcpy( label_ace, ace, ace->AceSize );
label_ace = (ACE_HEADER *)ace_next( label_ace );
memcpy( label_ace, ace, ace->size );
label_ace = ace_next( label_ace );
}
}
return label_acl;
@ -398,21 +373,20 @@ struct acl *extract_security_labels( const struct acl *sacl )
/* replace security labels in an existing SACL */
struct acl *replace_security_labels( const struct acl *old_sacl, const struct acl *new_sacl )
{
const ACE_HEADER *ace;
ACE_HEADER *replaced_ace;
size_t size = sizeof(*new_sacl);
const struct ace *ace;
struct ace *replaced_ace;
unsigned int i, count = 0;
BYTE revision = ACL_REVISION;
unsigned char revision = ACL_REVISION;
struct acl *replaced_acl;
data_size_t size = sizeof(*replaced_acl);
if (old_sacl)
{
revision = max( revision, old_sacl->revision );
ace = (const ACE_HEADER *)(old_sacl + 1);
for (i = 0; i < old_sacl->count; i++, ace = ace_next( ace ))
for (i = 0, ace = ace_first( old_sacl ); i < old_sacl->count; i++, ace = ace_next( ace ))
{
if (ace->AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE) continue;
size += ace->AceSize;
if (ace->type == SYSTEM_MANDATORY_LABEL_ACE_TYPE) continue;
size += ace->size;
count++;
}
}
@ -420,14 +394,18 @@ struct acl *replace_security_labels( const struct acl *old_sacl, const struct ac
if (new_sacl)
{
revision = max( revision, new_sacl->revision );
ace = (const ACE_HEADER *)(new_sacl + 1);
for (i = 0; i < new_sacl->count; i++, ace = ace_next( ace ))
for (i = 0, ace = ace_first( new_sacl ); i < new_sacl->count; i++, ace = ace_next( ace ))
{
if (ace->AceType != SYSTEM_MANDATORY_LABEL_ACE_TYPE) continue;
size += ace->AceSize;
if (ace->type != SYSTEM_MANDATORY_LABEL_ACE_TYPE) continue;
size += ace->size;
count++;
}
}
if (size > MAX_ACL_LEN)
{
set_error( STATUS_INVALID_ACL );
return NULL;
}
replaced_acl = mem_alloc( size );
if (!replaced_acl) return NULL;
@ -438,26 +416,24 @@ struct acl *replace_security_labels( const struct acl *old_sacl, const struct ac
replaced_acl->count = count;
replaced_acl->pad2 = 0;
replaced_ace = (ACE_HEADER *)(replaced_acl + 1);
replaced_ace = (struct ace *)(replaced_acl + 1);
if (old_sacl)
{
ace = (const ACE_HEADER *)(old_sacl + 1);
for (i = 0; i < old_sacl->count; i++, ace = ace_next( ace ))
for (i = 0, ace = ace_first( old_sacl ); i < old_sacl->count; i++, ace = ace_next( ace ))
{
if (ace->AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE) continue;
memcpy( replaced_ace, ace, ace->AceSize );
replaced_ace = (ACE_HEADER *)ace_next( replaced_ace );
if (ace->type == SYSTEM_MANDATORY_LABEL_ACE_TYPE) continue;
memcpy( replaced_ace, ace, ace->size );
replaced_ace = ace_next( replaced_ace );
}
}
if (new_sacl)
{
ace = (const ACE_HEADER *)(new_sacl + 1);
for (i = 0; i < new_sacl->count; i++, ace = ace_next( ace ))
for (i = 0, ace = ace_first( new_sacl ); i < new_sacl->count; i++, ace = ace_next( ace ))
{
if (ace->AceType != SYSTEM_MANDATORY_LABEL_ACE_TYPE) continue;
memcpy( replaced_ace, ace, ace->AceSize );
replaced_ace = (ACE_HEADER *)ace_next( replaced_ace );
if (ace->type != SYSTEM_MANDATORY_LABEL_ACE_TYPE) continue;
memcpy( replaced_ace, ace, ace->size );
replaced_ace = ace_next( replaced_ace );
}
}
@ -730,13 +706,10 @@ struct token *token_duplicate( struct token *src_token, unsigned primary,
static struct acl *create_default_dacl( const SID *user )
{
ACCESS_ALLOWED_ACE *aaa;
struct ace *ace;
struct acl *default_dacl;
SID *sid;
size_t default_dacl_size = sizeof(*default_dacl) +
2*(sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) +
sizeof(local_system_sid) +
security_sid_len( user );
size_t default_dacl_size = sizeof(*default_dacl) + 2 * sizeof(*ace) +
sizeof(local_system_sid) + security_sid_len( user );
default_dacl = mem_alloc( default_dacl_size );
if (!default_dacl) return NULL;
@ -748,23 +721,9 @@ static struct acl *create_default_dacl( const SID *user )
default_dacl->pad2 = 0;
/* GENERIC_ALL for Local System */
aaa = (ACCESS_ALLOWED_ACE *)(default_dacl + 1);
aaa->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
aaa->Header.AceFlags = 0;
aaa->Header.AceSize = (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) +
sizeof(local_system_sid);
aaa->Mask = GENERIC_ALL;
sid = (SID *)&aaa->SidStart;
memcpy( sid, &local_system_sid, sizeof(local_system_sid) );
ace = set_ace( ace_first( default_dacl ), &local_system_sid, ACCESS_ALLOWED_ACE_TYPE, 0, GENERIC_ALL );
/* GENERIC_ALL for specified user */
aaa = (ACCESS_ALLOWED_ACE *)((char *)aaa + aaa->Header.AceSize);
aaa->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
aaa->Header.AceFlags = 0;
aaa->Header.AceSize = (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) + security_sid_len( user );
aaa->Mask = GENERIC_ALL;
sid = (SID *)&aaa->SidStart;
memcpy( sid, user, security_sid_len( user ));
set_ace( ace_next( ace ), user, ACCESS_ALLOWED_ACE_TYPE, 0, GENERIC_ALL );
return default_dacl;
}
@ -779,11 +738,10 @@ struct sid_data
static struct security_descriptor *create_security_label_sd( struct token *token, PSID label_sid )
{
size_t sid_len = security_sid_len( label_sid ), sacl_size, sd_size;
SYSTEM_MANDATORY_LABEL_ACE *smla;
struct security_descriptor *sd;
struct acl *sacl;
sacl_size = sizeof(*sacl) + FIELD_OFFSET(SYSTEM_MANDATORY_LABEL_ACE, SidStart) + sid_len;
sacl_size = sizeof(*sacl) + sizeof(struct ace) + sid_len;
sd_size = sizeof(struct security_descriptor) + sacl_size;
if (!(sd = mem_alloc( sd_size )))
return NULL;
@ -801,13 +759,8 @@ static struct security_descriptor *create_security_label_sd( struct token *token
sacl->count = 1;
sacl->pad2 = 0;
smla = (SYSTEM_MANDATORY_LABEL_ACE *)(sacl + 1);
smla->Header.AceType = SYSTEM_MANDATORY_LABEL_ACE_TYPE;
smla->Header.AceFlags = 0;
smla->Header.AceSize = FIELD_OFFSET(SYSTEM_MANDATORY_LABEL_ACE, SidStart) + sid_len;
smla->Mask = SYSTEM_MANDATORY_LABEL_NO_WRITE_UP;
memcpy( &smla->SidStart, label_sid, sid_len );
set_ace( ace_first( sacl ), label_sid, SYSTEM_MANDATORY_LABEL_ACE_TYPE, 0,
SYSTEM_MANDATORY_LABEL_NO_WRITE_UP );
assert( sd_is_valid( sd, sd_size ) );
return sd;
}
@ -1028,7 +981,7 @@ static unsigned int token_access_check( struct token *token,
ULONG i;
const struct acl *dacl;
int dacl_present;
const ACE_HEADER *ace;
const struct ace *ace;
const SID *owner;
/* assume no access rights */
@ -1113,24 +1066,18 @@ static unsigned int token_access_check( struct token *token,
}
/* 4: Grant rights according to the DACL */
ace = (const ACE_HEADER *)(dacl + 1);
for (i = 0; i < dacl->count; i++, ace = ace_next( ace ))
for (i = 0, ace = ace_first( dacl ); i < dacl->count; i++, ace = ace_next( ace ))
{
const ACCESS_ALLOWED_ACE *aa_ace;
const ACCESS_DENIED_ACE *ad_ace;
const SID *sid;
const SID *sid = (const SID *)(ace + 1);
if (ace->AceFlags & INHERIT_ONLY_ACE)
continue;
if (ace->flags & INHERIT_ONLY_ACE) continue;
switch (ace->AceType)
switch (ace->type)
{
case ACCESS_DENIED_ACE_TYPE:
ad_ace = (const ACCESS_DENIED_ACE *)ace;
sid = (const SID *)&ad_ace->SidStart;
if (token_sid_present( token, sid, TRUE ))
{
unsigned int access = map_access( ad_ace->Mask, mapping );
unsigned int access = map_access( ace->mask, mapping );
if (desired_access & MAXIMUM_ALLOWED)
denied_access |= access;
else
@ -1141,11 +1088,9 @@ static unsigned int token_access_check( struct token *token,
}
break;
case ACCESS_ALLOWED_ACE_TYPE:
aa_ace = (const ACCESS_ALLOWED_ACE *)ace;
sid = (const SID *)&aa_ace->SidStart;
if (token_sid_present( token, sid, FALSE ))
{
unsigned int access = map_access( aa_ace->Mask, mapping );
unsigned int access = map_access( ace->mask, mapping );
if (desired_access & MAXIMUM_ALLOWED)
current_access |= access;
else

View File

@ -44,6 +44,7 @@
#include "winsock2.h"
#include "file.h"
#include "request.h"
#include "security.h"
#include "unicode.h"
static const void *cur_data;
@ -1047,7 +1048,7 @@ static void dump_varargs_SID( const char *prefix, data_size_t size )
static void dump_inline_acl( const char *prefix, const struct acl *acl, data_size_t size )
{
const ACE_HEADER *ace;
const struct ace *ace;
ULONG i;
fprintf( stderr,"%s{", prefix );
@ -1059,56 +1060,30 @@ static void dump_inline_acl( const char *prefix, const struct acl *acl, data_siz
return;
}
size -= sizeof(*acl);
ace = (const ACE_HEADER *)(acl + 1);
for (i = 0; i < acl->count; i++)
for (i = 0, ace = ace_first( acl ); i < acl->count; i++, ace = ace_next( ace ))
{
const SID *sid = NULL;
data_size_t sid_size = 0;
const SID *sid = (const SID *)(ace + 1);
data_size_t sid_size;
if (size < sizeof(ACE_HEADER) || size < ace->AceSize) break;
size -= ace->AceSize;
if (size < sizeof(*ace) || size < ace->size) break;
size -= ace->size;
sid_size = ace->size - sizeof(*ace);
if (i != 0) fputc( ',', stderr );
fprintf( stderr, "{AceType=" );
switch (ace->AceType)
fprintf( stderr, "{type=" );
switch (ace->type)
{
case ACCESS_DENIED_ACE_TYPE:
sid = (const SID *)&((const ACCESS_DENIED_ACE *)ace)->SidStart;
sid_size = ace->AceSize - FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart);
fprintf( stderr, "ACCESS_DENIED_ACE_TYPE,Mask=%x",
((const ACCESS_DENIED_ACE *)ace)->Mask );
break;
case ACCESS_ALLOWED_ACE_TYPE:
sid = (const SID *)&((const ACCESS_ALLOWED_ACE *)ace)->SidStart;
sid_size = ace->AceSize - FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart);
fprintf( stderr, "ACCESS_ALLOWED_ACE_TYPE,Mask=%x",
((const ACCESS_ALLOWED_ACE *)ace)->Mask );
break;
case SYSTEM_AUDIT_ACE_TYPE:
sid = (const SID *)&((const SYSTEM_AUDIT_ACE *)ace)->SidStart;
sid_size = ace->AceSize - FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart);
fprintf( stderr, "SYSTEM_AUDIT_ACE_TYPE,Mask=%x",
((const SYSTEM_AUDIT_ACE *)ace)->Mask );
break;
case SYSTEM_ALARM_ACE_TYPE:
sid = (const SID *)&((const SYSTEM_ALARM_ACE *)ace)->SidStart;
sid_size = ace->AceSize - FIELD_OFFSET(SYSTEM_ALARM_ACE, SidStart);
fprintf( stderr, "SYSTEM_ALARM_ACE_TYPE,Mask=%x",
((const SYSTEM_ALARM_ACE *)ace)->Mask );
break;
case SYSTEM_MANDATORY_LABEL_ACE_TYPE:
sid = (const SID *)&((const SYSTEM_MANDATORY_LABEL_ACE *)ace)->SidStart;
sid_size = ace->AceSize - FIELD_OFFSET(SYSTEM_MANDATORY_LABEL_ACE, SidStart);
fprintf( stderr, "SYSTEM_MANDATORY_LABEL_ACE_TYPE,Mask=%x",
((const SYSTEM_MANDATORY_LABEL_ACE *)ace)->Mask );
break;
case ACCESS_DENIED_ACE_TYPE: fprintf( stderr, "ACCESS_DENIED" ); break;
case ACCESS_ALLOWED_ACE_TYPE: fprintf( stderr, "ACCESS_ALLOWED" ); break;
case SYSTEM_AUDIT_ACE_TYPE: fprintf( stderr, "SYSTEM_AUDIT" ); break;
case SYSTEM_ALARM_ACE_TYPE: fprintf( stderr, "SYSTEM_ALARM" ); break;
case SYSTEM_MANDATORY_LABEL_ACE_TYPE: fprintf( stderr, "SYSTEM_MANDATORY_LABEL" ); break;
default:
fprintf( stderr, "unknown<%d>", ace->AceType );
fprintf( stderr, "%02x", ace->type );
sid = NULL;
break;
}
fprintf( stderr, ",AceFlags=%x", ace->AceFlags );
if (sid)
dump_inline_sid( ",Sid=", sid, sid_size );
ace = (const ACE_HEADER *)((const char *)ace + ace->AceSize);
fprintf( stderr, ",flags=%x,mask=%x", ace->flags, ace->mask );
if (sid) dump_inline_sid( ",sid=", sid, sid_size );
fputc( '}', stderr );
}
}