diff --git a/server/file.c b/server/file.c index 287a681cd68..f2f4f87b48b 100644 --- a/server/file.c +++ b/server/file.c @@ -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 */ diff --git a/server/process.c b/server/process.c index 4ffc065f0ba..8aea9deaa0e 100644 --- a/server/process.c +++ b/server/process.c @@ -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; } diff --git a/server/registry.c b/server/registry.c index 92ecc67d528..8187c12d5ce 100644 --- a/server/registry.c +++ b/server/registry.c @@ -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; } diff --git a/server/security.h b/server/security.h index cc3a98bb494..5fd9cd3269b 100644 --- a/server/security.h +++ b/server/security.h @@ -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 ); diff --git a/server/token.c b/server/token.c index 574cb1e5347..49168a77e10 100644 --- a/server/token.c +++ b/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 diff --git a/server/trace.c b/server/trace.c index 53e10c1a961..9516435769b 100644 --- a/server/trace.c +++ b/server/trace.c @@ -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 ); } }