From: "Erich E. Hoover" Subject: [PATCH 4/5] server: Return more security attribute information. Message-Id: Date: Thu, 1 Nov 2012 22:44:44 -0600 This patch changes the security information returned for files such that the group is returned as a separate DACL and the "Local System" DACL is only returned when any of the "other user" attributes are set. Without this patch, and the preceding patch, attempting to load Netflix will cause an Internet Connection Problem when the loading bar gets to 99% (Bug #31858). With this patch in place then Netflix still doesn't quite work, but it's very close - it will then play about 1 second of audio before stopping due to Bug #31993 (part 5). From 92b5f7fbe2df018fbd537b9a423112332cfa66fb Mon Sep 17 00:00:00 2001 From: Erich Hoover Date: Thu, 1 Nov 2012 22:26:35 -0600 Subject: server: Return more security attribute information. --- server/file.c | 62 ++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 18 deletions(-) diff --git a/server/file.c b/server/file.c index 3a8c964..06c1dce 100644 --- a/server/file.c +++ b/server/file.c @@ -323,11 +323,15 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID const SID *world_sid = security_world_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]); + dacl_size = sizeof(ACL); if (mode & S_IRWXU) dacl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]); + if (mode & S_IRWXG) + dacl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + + FIELD_OFFSET(SID, SubAuthority[group->SubAuthorityCount]) + + FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + + FIELD_OFFSET(SID, SubAuthority[local_system_sid->SubAuthorityCount]); 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)))) @@ -359,31 +363,21 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID dacl->AclRevision = ACL_REVISION; dacl->Sbz1 = 0; dacl->AclSize = dacl_size; - dacl->AceCount = 1 + (mode & S_IRWXU ? 1 : 0) + (mode & S_IRWXO ? 1 : 0); + dacl->AceCount = (mode & S_IRWXU ? 1 : 0) + (mode & S_IRWXG ? 1 : 0) + (mode & S_IRWXO ? 2 : 0); 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->AceCount++; dacl->Sbz2 = 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 = 0; - aaa->Header.AceSize = FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + - FIELD_OFFSET(SID, SubAuthority[local_system_sid->SubAuthorityCount]); - aaa->Mask = FILE_ALL_ACCESS; - sid = (SID *)&aaa->SidStart; - memcpy( sid, local_system_sid, FIELD_OFFSET(SID, SubAuthority[local_system_sid->SubAuthorityCount]) ); 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 = 0; + aaa->Header.AceFlags = OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE; aaa->Header.AceSize = FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]); aaa->Mask = WRITE_DAC | WRITE_OWNER; @@ -393,14 +387,33 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID aaa->Mask |= FILE_GENERIC_WRITE | DELETE | FILE_DELETE_CHILD; sid = (SID *)&aaa->SidStart; memcpy( sid, user, FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]) ); + aaa = (ACCESS_ALLOWED_ACE *)ace_next( current_ace ); + current_ace = &aaa->Header; + } + if (mode & S_IRWXG) + { + /* appropriate access rights for the group */ + aaa->Header.AceType = ACCESS_ALLOWED_ACE_TYPE; + aaa->Header.AceFlags = OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE; + aaa->Header.AceSize = FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + + FIELD_OFFSET(SID, SubAuthority[group->SubAuthorityCount]); + aaa->Mask = WRITE_DAC | WRITE_OWNER; + if (mode & S_IRGRP) + aaa->Mask |= FILE_GENERIC_READ | FILE_GENERIC_EXECUTE; + if (mode & S_IWGRP) + aaa->Mask |= FILE_GENERIC_WRITE | DELETE | FILE_DELETE_CHILD; + sid = (SID *)&aaa->SidStart; + memcpy( sid, group, FIELD_OFFSET(SID, SubAuthority[group->SubAuthorityCount]) ); + aaa = (ACCESS_ALLOWED_ACE *)ace_next( current_ace ); + current_ace = &aaa->Header; } 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)))) { + ACCESS_DENIED_ACE *ada = (ACCESS_DENIED_ACE *)aaa; + /* 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 = 0; ada->Header.AceSize = FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + @@ -413,12 +426,12 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID ada->Mask &= ~STANDARD_RIGHTS_ALL; /* never deny standard rights */ sid = (SID *)&ada->SidStart; memcpy( sid, user, FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]) ); + aaa = (ACCESS_ALLOWED_ACE *)ace_next( current_ace ); + current_ace = &aaa->Header; } 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 = 0; aaa->Header.AceSize = FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + @@ -430,6 +443,19 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID aaa->Mask |= FILE_GENERIC_WRITE | DELETE | FILE_DELETE_CHILD; sid = (SID *)&aaa->SidStart; memcpy( sid, world_sid, FIELD_OFFSET(SID, SubAuthority[world_sid->SubAuthorityCount]) ); + aaa = (ACCESS_ALLOWED_ACE *)ace_next( current_ace ); + current_ace = &aaa->Header; + + /* give FILE_ALL_ACCESS for Local System of Everyone has any rights at all */ + 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->Mask = FILE_ALL_ACCESS; + sid = (SID *)&aaa->SidStart; + memcpy( sid, local_system_sid, FIELD_OFFSET(SID, SubAuthority[local_system_sid->SubAuthorityCount]) ); + aaa = (ACCESS_ALLOWED_ACE *)ace_next( current_ace ); + current_ace = &aaa->Header; } return sd; -- 1.7.9.5