server: Add a helper function to compute an SID length.

This commit is contained in:
Alexandre Julliard 2013-04-11 12:52:08 +02:00
parent 33d31a3547
commit 62beef5a72
4 changed files with 35 additions and 40 deletions

View File

@ -319,28 +319,24 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID
const SID *local_system_sid = security_local_system_sid;
dacl_size = sizeof(ACL) + FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) +
FIELD_OFFSET(SID, SubAuthority[local_system_sid->SubAuthorityCount]);
security_sid_len( local_system_sid );
if (mode & S_IRWXU)
dacl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) +
FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]);
dacl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + 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) +
FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]);
dacl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + security_sid_len( user );
if (mode & S_IRWXO)
dacl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) +
FIELD_OFFSET(SID, SubAuthority[world_sid->SubAuthorityCount]);
dacl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + security_sid_len( world_sid );
sd = mem_alloc( sizeof(struct security_descriptor) +
FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]) +
FIELD_OFFSET(SID, SubAuthority[group->SubAuthorityCount]) +
security_sid_len( user ) + security_sid_len( group ) +
dacl_size );
if (!sd) return sd;
sd->control = SE_DACL_PRESENT;
sd->owner_len = FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]);
sd->group_len = FIELD_OFFSET(SID, SubAuthority[group->SubAuthorityCount]);
sd->owner_len = security_sid_len( user );
sd->group_len = security_sid_len( group );
sd->sacl_len = 0;
sd->dacl_len = dacl_size;
@ -366,11 +362,10 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID
current_ace = &aaa->Header;
aaa->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
aaa->Header.AceFlags = 0;
aaa->Header.AceSize = FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) +
FIELD_OFFSET(SID, SubAuthority[local_system_sid->SubAuthorityCount]);
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, FIELD_OFFSET(SID, SubAuthority[local_system_sid->SubAuthorityCount]) );
memcpy( sid, local_system_sid, security_sid_len( local_system_sid ));
if (mode & S_IRWXU)
{
@ -379,15 +374,14 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID
current_ace = &aaa->Header;
aaa->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
aaa->Header.AceFlags = 0;
aaa->Header.AceSize = FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) +
FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]);
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, FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]) );
memcpy( sid, user, security_sid_len( user ));
}
if ((!(mode & S_IRUSR) && (mode & (S_IRGRP|S_IROTH))) ||
(!(mode & S_IWUSR) && (mode & (S_IWGRP|S_IWOTH))) ||
@ -398,8 +392,7 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID
current_ace = &ada->Header;
ada->Header.AceType = ACCESS_DENIED_ACE_TYPE;
ada->Header.AceFlags = 0;
ada->Header.AceSize = FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) +
FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]);
ada->Header.AceSize = FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + security_sid_len( user );
ada->Mask = 0;
if (!(mode & S_IRUSR) && (mode & (S_IRGRP|S_IROTH)))
ada->Mask |= FILE_GENERIC_READ | FILE_GENERIC_EXECUTE;
@ -407,7 +400,7 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID
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, FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]) );
memcpy( sid, user, security_sid_len( user ));
}
if (mode & S_IRWXO)
{
@ -416,15 +409,14 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID
current_ace = &aaa->Header;
aaa->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
aaa->Header.AceFlags = 0;
aaa->Header.AceSize = FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) +
FIELD_OFFSET(SID, SubAuthority[world_sid->SubAuthorityCount]);
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, FIELD_OFFSET(SID, SubAuthority[world_sid->SubAuthorityCount]) );
memcpy( sid, world_sid, security_sid_len( world_sid ));
}
return sd;

View File

@ -443,7 +443,7 @@ int default_set_sd( struct object *obj, const struct security_descriptor *sd,
else
{
owner = token_get_user( current->process->token );
new_sd.owner_len = FIELD_OFFSET(SID, SubAuthority[owner->SubAuthorityCount]);
new_sd.owner_len = security_sid_len( owner );
new_sd.control |= SE_OWNER_DEFAULTED;
}
@ -453,7 +453,7 @@ int default_set_sd( struct object *obj, const struct security_descriptor *sd,
else
{
group = token_get_primary_group( current->process->token );
new_sd.group_len = FIELD_OFFSET(SID, SubAuthority[group->SubAuthorityCount]);
new_sd.group_len = security_sid_len( group );
new_sd.control |= SE_GROUP_DEFAULTED;
}

View File

@ -62,10 +62,15 @@ static inline const ACE_HEADER *ace_next( const ACE_HEADER *ace )
return (const ACE_HEADER *)((const char *)ace + ace->AceSize);
}
static inline size_t security_sid_len( const SID *sid )
{
return offsetof( SID, SubAuthority[sid->SubAuthorityCount] );
}
static inline int security_equal_sid( const SID *sid1, const SID *sid2 )
{
return ((sid1->SubAuthorityCount == sid2->SubAuthorityCount) &&
!memcmp( sid1, sid2, FIELD_OFFSET(SID, SubAuthority[sid1->SubAuthorityCount]) ));
!memcmp( sid1, sid2, security_sid_len( sid1 )));
}
extern void security_set_thread_token( struct thread *thread, obj_handle_t handle );

View File

@ -252,8 +252,7 @@ static int acl_is_valid( const ACL *acl, data_size_t size )
default:
return FALSE;
}
if (sid_size < FIELD_OFFSET(SID, SubAuthority[0]) ||
sid_size < FIELD_OFFSET(SID, SubAuthority[sid->SubAuthorityCount]))
if (sid_size < FIELD_OFFSET(SID, SubAuthority[0]) || sid_size < security_sid_len( sid ))
return FALSE;
ace = ace_next( ace );
}
@ -280,7 +279,7 @@ int sd_is_valid( const struct security_descriptor *sd, data_size_t size )
owner = sd_get_owner( sd );
if (owner)
{
size_t needed_size = FIELD_OFFSET(SID, SubAuthority[owner->SubAuthorityCount]);
size_t needed_size = security_sid_len( owner );
if ((sd->owner_len < sizeof(SID)) || (needed_size > sd->owner_len))
return FALSE;
}
@ -292,7 +291,7 @@ int sd_is_valid( const struct security_descriptor *sd, data_size_t size )
group = sd_get_group( sd );
if (group)
{
size_t needed_size = FIELD_OFFSET(SID, SubAuthority[group->SubAuthorityCount]);
size_t needed_size = security_sid_len( group );
if ((sd->group_len < sizeof(SID)) || (needed_size > sd->group_len))
return FALSE;
}
@ -454,7 +453,7 @@ static struct token *create_token( unsigned primary, const SID *user,
token->primary_group = NULL;
/* copy user */
token->user = memdup( user, FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]) );
token->user = memdup( user, security_sid_len( user ));
if (!token->user)
{
release_object( token );
@ -472,7 +471,7 @@ static struct token *create_token( unsigned primary, const SID *user,
release_object( token );
return NULL;
}
memcpy( &group->sid, groups[i].Sid, FIELD_OFFSET( SID, SubAuthority[((const SID *)groups[i].Sid)->SubAuthorityCount] ) );
memcpy( &group->sid, groups[i].Sid, security_sid_len( groups[i].Sid ));
group->enabled = TRUE;
group->def = TRUE;
group->logon = (groups[i].Attributes & SE_GROUP_LOGON_ID) != 0;
@ -574,7 +573,7 @@ static ACL *create_default_dacl( const SID *user )
size_t default_dacl_size = sizeof(ACL) +
2*(sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) +
sizeof(local_system_sid) +
FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]);
security_sid_len( user );
default_dacl = mem_alloc( default_dacl_size );
if (!default_dacl) return NULL;
@ -599,11 +598,10 @@ static ACL *create_default_dacl( const SID *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)) +
FIELD_OFFSET( SID, SubAuthority[user->SubAuthorityCount] );
aaa->Header.AceSize = (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) + security_sid_len( user );
aaa->Mask = GENERIC_ALL;
sid = (SID *)&aaa->SidStart;
memcpy( sid, user, FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]) );
memcpy( sid, user, security_sid_len( user ));
return default_dacl;
}
@ -1275,7 +1273,7 @@ DECL_HANDLER(get_token_sid)
if (sid)
{
reply->sid_len = FIELD_OFFSET(SID, SubAuthority[sid->SubAuthorityCount]);
reply->sid_len = security_sid_len( sid );
if (reply->sid_len <= get_reply_max_size()) set_reply_data( sid, reply->sid_len );
else set_error( STATUS_BUFFER_TOO_SMALL );
}
@ -1302,7 +1300,7 @@ DECL_HANDLER(get_token_groups)
LIST_FOR_EACH_ENTRY( group, &token->groups, const struct group, entry )
{
group_count++;
sid_size += FIELD_OFFSET(SID, SubAuthority[group->sid.SubAuthorityCount]);
sid_size += security_sid_len( &group->sid );
}
size_needed += sid_size;
/* attributes size */
@ -1340,9 +1338,9 @@ DECL_HANDLER(get_token_groups)
if (group->resource) *attr_ptr |= SE_GROUP_RESOURCE;
if (group->logon) *attr_ptr |= SE_GROUP_LOGON_ID;
memcpy(sid_ptr, &group->sid, FIELD_OFFSET(SID, SubAuthority[group->sid.SubAuthorityCount]));
memcpy(sid_ptr, &group->sid, security_sid_len( &group->sid ));
sid_ptr = (SID *)((char *)sid_ptr + FIELD_OFFSET(SID, SubAuthority[group->sid.SubAuthorityCount]));
sid_ptr = (SID *)((char *)sid_ptr + security_sid_len( &group->sid ));
attr_ptr++;
}
}