server: Define a server-side structure for ACE.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
c36f81fa75
commit
841b8862fb
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
|
|
165
server/token.c
165
server/token.c
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue