Mail Archives: cygwin-developers/1999/03/05/16:54:19
This is a multi-part message in MIME format.
--------------76F080FB75CF85B656CAA21C
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Geoffrey Noer wrote:
> [...]
> I have your original patch applied. The resulting cygwin1.dll builds
> but doesn't run close to correctly on my NT 4 SP4 machine as expected.
> Please send me the patch that gets around the two above problems in
> the way you suggest and I'll try it out...
Hello Geoffrey,
the changes are only in security.cc. I attached a patch
relativ to the original security.cc from the current snapshots.
Regards,
Corinna
--------------76F080FB75CF85B656CAA21C
Content-Type: text/plain; charset=us-ascii; name="sec-diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="sec-diff"
Index: security.cc
===================================================================
RCS file: /src/cvsroot/winsup-990126/security.cc,v
retrieving revision 1.1
diff -u -p -r1.1 security.cc
--- security.cc 1999/01/29 09:33:43 1.1
+++ security.cc 1999/03/05 08:11:08
@@ -1,8 +1,9 @@
/* security.cc: NT security functions
- Copyright 1997, 1998 Cygnus Solutions.
+ Copyright 1997, 1998, 1999 Cygnus Solutions.
- Written by Gunther Ebert, gunther DOT ebert AT ixos-leipzig DOT de
+ Originaly written by Gunther Ebert, gunther DOT ebert AT ixos-leipzig DOT de
+ Extensions by Corinna Vinschen <corinna DOT vinschen AT cityweb DOT de>
This file is part of Cygwin.
@@ -13,23 +14,35 @@ details. */
#include <grp.h>
#include <pwd.h>
#include <unistd.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
#include "winsup.h"
-#if 0
+extern BOOL allow_ntea;
+BOOL allow_ntsec = FALSE;
+
+extern PSID get_admin_sid ();
+
PSID
get_world_sid ()
{
- PSID world_sid;
- SID_IDENTIFIER_AUTHORITY world_sid_auth = SECURITY_WORLD_SID_AUTHORITY;
+ static PSID world_sid;
- world_sid = (PSID) LocalAlloc (LPTR,GetSidLengthRequired (1));
+ if (! world_sid)
+ {
+ SID_IDENTIFIER_AUTHORITY world_sid_auth = SECURITY_WORLD_SID_AUTHORITY;
+
+ world_sid = (PSID) LocalAlloc (LPTR,GetSidLengthRequired (1));
- InitializeSid (world_sid, &world_sid_auth, 1);
- *(GetSidSubAuthority (world_sid, 0)) = SECURITY_WORLD_RID;
+ InitializeSid (world_sid, &world_sid_auth, 1);
+ *(GetSidSubAuthority (world_sid, 0)) = SECURITY_WORLD_RID;
+ }
return world_sid;
}
+#if 0
int
world_full_access (HANDLE h, int type)
{
@@ -153,22 +166,417 @@ get_id_from_sid (PSID psid)
return id;
}
+
+static BOOL
+get_nt_attribute (const char *file, int *attribute)
+{
+ if (os_being_run != winNT)
+ return FALSE;
+
+ syscall_printf ("file: %s", file);
+
+ if (file[1] == ':')
+ {
+ static char drive[4] = "X:\\";
+ char fs[32];
+
+ drive[0] = file[0];
+ if (! GetVolumeInformation(drive, NULL, 0, NULL, NULL, NULL, fs, 32))
+ {
+ debug_printf ("GetVolumeInformation(%s) %d", drive, GetLastError());
+ return FALSE;
+ }
+ if (! strcmp (fs, "FAT"))
+ return FALSE;
+ }
+
+ DWORD sd_size = 0;
+ DWORD bufdummy;
+ SECURITY_DESCRIPTOR *sd = (SECURITY_DESCRIPTOR *) &bufdummy;
+
+ if (! GetFileSecurity (file, OWNER_SECURITY_INFORMATION
+ | GROUP_SECURITY_INFORMATION
+ | DACL_SECURITY_INFORMATION,
+ sd, 4, &sd_size))
+ {
+ debug_printf ("GetFileSecuritySize %d", GetLastError());
+ if (sd_size == 0)
+ return FALSE;
+ }
+ sd = (SECURITY_DESCRIPTOR *) malloc (sd_size);
+ if (! sd)
+ {
+ debug_printf ("malloc");
+ return FALSE;
+ }
+ if (! GetFileSecurity (file, OWNER_SECURITY_INFORMATION
+ | GROUP_SECURITY_INFORMATION
+ | DACL_SECURITY_INFORMATION,
+ sd, sd_size, &sd_size))
+ {
+ free (sd);
+ debug_printf ("GetFileSecurity %d", GetLastError ());
+ return FALSE;
+ }
-/*
- * File attribute stuff. FIXME: add NTFS security.
- */
+ PSID sidOwner;
+ PSID sidGroup;
+ BOOL dummy;
+
+ if (! GetSecurityDescriptorOwner (sd, &sidOwner, &dummy))
+ debug_printf ("GetSecurityDescriptorOwner %d", GetLastError ());
+ if (! GetSecurityDescriptorGroup (sd, &sidGroup, &dummy))
+ debug_printf ("GetSecurityDescriptorGroup %d", GetLastError ());
+
+ int owner_id = -1;
+ if (sidOwner)
+ owner_id = *GetSidSubAuthority(sidOwner,
+ *GetSidSubAuthorityCount(sidOwner) - 1);
+ int group_id = -1;
+ if (sidGroup)
+ group_id = *GetSidSubAuthority(sidGroup,
+ *GetSidSubAuthorityCount(sidGroup) - 1);
+ PACL acl;
+ BOOL acl_exists;
+
+ if (! GetSecurityDescriptorDacl (sd, &acl_exists, &acl, &dummy)
+ || ! acl_exists)
+ {
+ free (sd);
+ debug_printf ("GetSecurityDescriptorDacl %d", GetLastError ());
+ return FALSE;
+ }
+
+ BOOL has_owner_bits = FALSE;
+ BOOL has_group_bits = FALSE;
+ BOOL has_world_bits = FALSE;
+
+ for (DWORD i = 0; i < acl->AceCount; ++i)
+ {
+ ACCESS_ALLOWED_ACE *ace;
+
+ if (GetAce (acl, i, (PVOID *) &ace))
+ {
+ int ace_id = *GetSidSubAuthority((PSID) &ace->SidStart,
+ *GetSidSubAuthorityCount((PSID) &ace->SidStart) - 1);
+ switch (ace->Header.AceType)
+ {
+ case ACCESS_ALLOWED_ACE_TYPE:
+ if (owner_id >= 0 && ace_id == owner_id)
+ {
+ *attribute &= ~S_IRWXU;
+ has_owner_bits = TRUE;
+ if (ace->Mask & FILE_READ_DATA)
+ *attribute |= S_IRUSR;
+ if (ace->Mask & FILE_WRITE_DATA)
+ *attribute |= S_IWUSR;
+ if (ace->Mask & FILE_EXECUTE)
+ *attribute |= S_IXUSR;
+ }
+ else if (group_id && ace_id == group_id)
+ {
+ *attribute &= ~S_IRWXG;
+ has_group_bits = TRUE;
+ if (ace->Mask & FILE_READ_DATA)
+ *attribute |= S_IRGRP;
+ if (ace->Mask & FILE_WRITE_DATA)
+ *attribute |= S_IWGRP;
+ if (ace->Mask & FILE_EXECUTE)
+ *attribute |= S_IXGRP;
+ }
+ else if (ace_id == 0)
+ {
+ *attribute &= ~S_IRWXO;
+ has_world_bits = TRUE;
+ if (ace->Mask & FILE_READ_DATA)
+ {
+ *attribute |= S_IROTH;
+ if (! sidOwner || ! has_owner_bits)
+ *attribute |= S_IRUSR;
+ if (! sidGroup || ! has_group_bits)
+ *attribute |= S_IRGRP;
+ }
+ if (ace->Mask & FILE_WRITE_DATA)
+ {
+ *attribute |= S_IWOTH;
+ if (! sidOwner || ! has_owner_bits)
+ *attribute |= S_IWUSR;
+ if (! sidGroup || ! has_group_bits)
+ *attribute |= S_IWGRP;
+ }
+ if (ace->Mask & FILE_EXECUTE)
+ {
+ *attribute |= S_IXOTH;
+ if (! sidOwner || ! has_owner_bits)
+ *attribute |= S_IXUSR;
+ if (! sidGroup || ! has_group_bits)
+ *attribute |= S_IXGRP;
+ }
+ }
+ break;
+ case ACCESS_DENIED_ACE_TYPE:
+ // Still ignored!
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ free (sd);
+ syscall_printf ("file: %s %x", file, *attribute);
+ return TRUE;
+}
+
BOOL
get_file_attribute (const char *file, int *attribute)
{
+ if (! attribute)
+ return FALSE;
+
int res = NTReadEA (file, ".UNIXATTR", (char *) attribute,
sizeof (*attribute));
- return res > 0;
+
+ // symlinks are anything for everyone!
+ if ((*attribute & S_IFLNK) == S_IFLNK)
+ *attribute |= S_IRWXU | S_IRWXG | S_IRWXO;
+
+ if (!allow_ntsec)
+ return res > 0;
+
+ return get_nt_attribute (file, attribute);
+}
+
+static BOOL
+set_nt_attribute (const char *file, uid_t uid, gid_t gid, int attribute)
+{
+ if (os_being_run != winNT)
+ return FALSE;
+
+ DWORD sidlen, domlen;
+ char dom[100];
+ char user[256];
+ SID_NAME_USE acc_type;
+
+ /*
+ * Caution!
+ *
+ * ID 513 is `none'. Giving explicit permissions
+ * to `none' will result in dubious problems!
+ *
+ * Uid 513 is definitely not allowed here!
+ */
+ if (uid == 513)
+ return FALSE;
+
+ struct passwd *pw = getpwuid (uid);
+ strcpy (user, pw ? pw->pw_name : getlogin ());
+ PSID sidOwner = (PSID) malloc (1024);
+ if (! sidOwner)
+ {
+ debug_printf ("malloc 1");
+ return FALSE;
+ }
+ if (! LookupAccountName (NULL, user,
+ sidOwner, (sidlen = 1024, &sidlen),
+ dom, (domlen = 100, &domlen),
+ &acc_type))
+ {
+ free (sidOwner);
+ debug_printf ("LookupAccountName(%s) %d", user, GetLastError ());
+ return FALSE;
+ }
+ else if (acc_type != SidTypeUser)
+ {
+ char domuser[356];
+ strcpy (domuser, dom);
+ strcat (domuser, "\\");
+ strcat (domuser, user);
+ if (! LookupAccountName (NULL, domuser,
+ sidOwner, (sidlen = 1024, &sidlen),
+ dom, (domlen = 100, &domlen),
+ &acc_type))
+ {
+ free (sidOwner);
+ debug_printf ("LookupAccountName(%s) %d", domuser, GetLastError ());
+ return FALSE;
+ }
+ }
+ sidOwner = (PSID) realloc (sidOwner, sidlen + 1);
+ debug_printf ("user: %s [%d]", user,
+ *GetSidSubAuthority((PSID) sidOwner,
+ *GetSidSubAuthorityCount((PSID) sidOwner) - 1));
+
+ struct group *grp = getgrgid (gid);
+ PSID sidGroup = NULL;
+
+ /*
+ * Caution!
+ *
+ * ID 513 is `none'. Giving explicit permissions
+ * to `none' will result in dubious problems!
+ *
+ * Gid 513 will result in not setting group permissions here.
+ */
+ if (grp && gid != 513)
+ {
+ sidGroup = (PSID) malloc (1024);
+ if (! sidGroup)
+ {
+ free (sidOwner);
+ free (sidGroup);
+ debug_printf ("malloc 2");
+ return FALSE;
+ }
+ if (! LookupAccountName (NULL, grp->gr_name,
+ sidGroup, (sidlen = 1024, &sidlen),
+ dom, (domlen = 100, &domlen),
+ &acc_type))
+ {
+ free (sidOwner);
+ free (sidGroup);
+ debug_printf ("LookupAccountName(%s) %d", grp->gr_name,
+ GetLastError ());
+ return FALSE;
+ }
+ sidGroup = (PSID) realloc (sidGroup, sidlen + 1);
+ debug_printf ("group: %s [%d]", grp->gr_name,
+ *GetSidSubAuthority((PSID) sidGroup,
+ *GetSidSubAuthorityCount((PSID) sidGroup) - 1));
+ }
+ else
+ debug_printf ("no group");
+
+ SECURITY_DESCRIPTOR sd;
+
+ if (! InitializeSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION))
+ debug_printf ("InitializeSecurityDescriptor %d", GetLastError ());
+ if (! SetSecurityDescriptorOwner(&sd, sidOwner, FALSE))
+ debug_printf ("SetSecurityDescriptorOwner %d", GetLastError ());
+ if (sidGroup)
+ if (! SetSecurityDescriptorGroup(&sd, sidGroup, FALSE))
+ debug_printf ("SetSecurityDescriptorGroup %d", GetLastError ());
+
+ size_t acl_len = sizeof (ACL)
+ + 3 * (sizeof (ACCESS_ALLOWED_ACE) - sizeof (DWORD))
+ + GetLengthSid (sidOwner)
+ + GetLengthSid (get_admin_sid ())
+ + GetLengthSid (get_world_sid ());
+ if (sidGroup)
+ acl_len += sizeof (ACCESS_ALLOWED_ACE)
+ - sizeof (DWORD)
+ + GetLengthSid (sidGroup);
+
+ PACL acl = (PACL) malloc (acl_len);
+ if (! acl)
+ {
+ free (sidOwner);
+ free (sidGroup);
+ debug_printf ("malloc 4");
+ return FALSE;
+ }
+ if (! InitializeAcl (acl, acl_len, ACL_REVISION))
+ debug_printf ("InitializeAcl %d", GetLastError ());
+
+ int ace_off = 0;
+ ACCESS_ALLOWED_ACE *ace;
+
+ DWORD access = STANDARD_RIGHTS_ALL;
+ if (attribute & S_IRUSR)
+ access |= FILE_GENERIC_READ | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA;
+ if (attribute & S_IWUSR)
+ access |= FILE_GENERIC_WRITE | DELETE | FILE_DELETE_CHILD;
+ if (attribute & S_IXUSR)
+ access |= FILE_GENERIC_EXECUTE;
+ if (! AddAccessAllowedAce (acl, ACL_REVISION, access, sidOwner))
+ debug_printf ("AddAccessAllowedAce(owner) %d", GetLastError ());
+ if (GetAce(acl, 0, (PVOID *) &ace))
+ ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
+
+ if (! sidGroup || ! EqualSid (sidGroup, get_admin_sid ()))
+ {
+ if (! AddAccessAllowedAce (acl, ACL_REVISION,
+ SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL,
+ get_admin_sid ()))
+ debug_printf ("AddAccessAllowedAce(admin) %d", GetLastError ());
+ if (GetAce(acl, 1, (PVOID *) &ace))
+ ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
+ ace_off = 1;
+ }
+
+ if (sidGroup)
+ {
+ access = 0;
+ if (attribute & S_IRGRP)
+ {
+ access |= FILE_GENERIC_READ;
+ if (EqualSid (sidGroup, get_admin_sid ()))
+ access |= FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA;
+ }
+ if (attribute & S_IWGRP)
+ access |= STANDARD_RIGHTS_ALL | FILE_GENERIC_WRITE
+ | DELETE | FILE_DELETE_CHILD;
+ if (attribute & S_IXGRP)
+ access |= FILE_GENERIC_EXECUTE;
+ if (! AddAccessAllowedAce (acl, ACL_REVISION, access, sidGroup))
+ debug_printf ("AddAccessAllowedAce(group) %d", GetLastError ());
+ if (GetAce(acl, 1 + ace_off, (PVOID *) &ace))
+ ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
+ }
+
+ access = 0;
+ if (attribute & S_IROTH)
+ access |= FILE_GENERIC_READ;
+ if (attribute & S_IWOTH)
+ access |= STANDARD_RIGHTS_ALL | FILE_GENERIC_WRITE
+ | DELETE | FILE_DELETE_CHILD;
+ if (attribute & S_IXOTH)
+ access |= FILE_GENERIC_EXECUTE;
+ if (! AddAccessAllowedAce (acl, ACL_REVISION, access, get_world_sid ()))
+ debug_printf ("AddAccessAllowedAce(world) %d", GetLastError ());
+ if (GetAce(acl, 2 + ace_off, (PVOID *) &ace))
+ ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
+
+ if (! SetSecurityDescriptorDacl (&sd, TRUE, acl, FALSE))
+ debug_printf ("SetSecurityDescriptorDacl %d", GetLastError ());
+
+ if (! SetFileSecurity (file,
+ OWNER_SECURITY_INFORMATION
+ | (grp ? GROUP_SECURITY_INFORMATION : 0)
+ | DACL_SECURITY_INFORMATION,
+ &sd))
+ debug_printf ("SetFileSecurity %d", GetLastError());
+
+ free (sidOwner);
+ free (sidGroup);
+ free (acl);
+
+ return TRUE;
+}
+
+BOOL
+set_file_attribute (const char *file, uid_t uid, gid_t gid, int attribute)
+{
+ // symlinks are anything for everyone!
+ if ((attribute & S_IFLNK) == S_IFLNK)
+ attribute |= S_IRWXU | S_IRWXG | S_IRWXO;
+
+ BOOL ret = NTWriteEA (file, ".UNIXATTR",
+ (char *) &attribute, sizeof (attribute));
+
+ if (!allow_ntsec)
+ return ret;
+
+ ret = set_nt_attribute (file, uid, gid, attribute);
+
+ syscall_printf ("%d = set_file_attribute (%s, %d, %d, %p)", ret, file, uid, gid, attribute);
+
+ return ret;
}
BOOL
set_file_attribute (const char *file, int attribute)
{
- return NTWriteEA (file, ".UNIXATTR", (char *) &attribute,
- sizeof (attribute));
+ return set_file_attribute (file, myself->uid, myself->gid, attribute);
}
--------------76F080FB75CF85B656CAA21C--
- Raw text -