From: corinna DOT vinschen AT cityweb DOT de (Corinna Vinschen) Subject: Re: Patch: UNIX-like permissions on objects 22 Jan 1999 19:54:34 -0800 Message-ID: <36A94430.E65E3C10.cygnus.cygwin32.developers@cityweb.de> References: <01BE4603 DOT 818F4910 AT sos> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit To: Sergey Okhapkin Cc: "cygwin32-developers AT cygnus DOT com" , Christopher Faylor Sergey Okhapkin wrote: > > Corinna Vinschen wrote: > > I have created two new functions, which give permissions > > to objects so, that not only the owner, but the administrator > > or administrator group too, has all permissions on the object. > > > > Will you extend your patch for file security and mapping unix access rights into NT's permissions? The following patch seems to work. It is not complete, but it shows, how it could work. The main patch is in security.cc. The function `mkdir()' in dir.cc now calls `set_file_attribute()', too. But some applications behave strange now. E.g. cvs: With this patch, it's impossible, to commit changes, because the user, which creates the lock file, has suddenly no write permissions to this lock file anymore. I don't understand why! Possibly, it's a bug, not to change the SECURITY_DESCRIPTOR's to absolut format? Moreover, I haven't found out, how to set the default file permissions in a directory security descriptor. Who knows, how to do this? The change to shared.cc:sec_user() was a typo. The change to sigproc.cc:getsem() now calls sec_user() instead of sec_user_nih(). This seems to solve an access problem. If CreateSemaphore() calls sec_user_nih(), you will often see a message like this, but in any case, the Error is ACCESS_DENIED. 0 0 [sig] D:\bin\sh.exe 1063 getsem: can't open cygwinS1.sigcatch.319, error 5 Would you, Sergey, be so kind, to take a look into the code and eventually test it? Again: Any opinions, error messages, fixes etc. are appreciated. Regards, Corinna Index: shared.cc =================================================================== RCS file: /src/cvsroot/winsup-981230/shared.cc,v retrieving revision 1.2 diff -u -p -1 -r1.2 shared.cc --- shared.cc 1999/01/23 01:29:14 1.2 +++ shared.cc 1999/01/23 01:29:25 @@ -283,3 +283,3 @@ sec_user (BOOL inherit) strcat (domuser, "\\"); - strcpy (domuser, getlogin ()); + strcat (domuser, getlogin ()); if (! LookupAccountName (NULL, domuser, Index: sigproc.cc =================================================================== RCS file: /src/cvsroot/winsup-981230/sigproc.cc,v retrieving revision 1.2 diff -u -p -1 -r1.2 sigproc.cc --- sigproc.cc 1998/12/31 13:27:54 1.2 +++ sigproc.cc 1999/01/23 02:02:14 @@ -773,3 +773,3 @@ sig_send (pinfo *p, int sig) goto out; // Couldn't get the semaphore. getsem issued - // an error, if appropriate. + // an error, if appropriate. @@ -1070,3 +1070,3 @@ getsem (pinfo *p, const char *str, int i DWORD winpid = GetCurrentProcessId (); - h = CreateSemaphore (sec_user_nih (), init, max, str = shared_name (str, winpid)); + h = CreateSemaphore (sec_user (), init, max, str = shared_name (str, winpid)); p = myself; Index: dir.cc =================================================================== RCS file: /src/cvsroot/winsup-981230/dir.cc,v retrieving revision 1.1.1.1 diff -u -p -1 -r1.1.1.1 dir.cc --- dir.cc 1998/12/30 23:01:57 1.1.1.1 +++ dir.cc 1999/01/23 01:00:37 @@ -273,3 +273,7 @@ mkdir (const char *dir, mode_t mode) if (CreateDirectoryA (real_dir.get_win32 (), 0)) - res = 0; + { + set_file_attribute (real_dir.get_win32 (), + (mode & 0777) & ~myself->umask); + res = 0; + } else Index: security.cc =================================================================== RCS file: /src/cvsroot/winsup-981230/security.cc,v retrieving revision 1.1.1.1 diff -u -p -1 -r1.1.1.1 security.cc --- security.cc 1998/12/30 23:01:58 1.1.1.1 +++ security.cc 1999/01/23 02:48:56 @@ -15,5 +15,9 @@ details. */ #include +#include +#include +#include #include "winsup.h" -#if 0 +extern PSID get_admin_sid (); + PSID @@ -21,9 +25,13 @@ 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; - InitializeSid (world_sid, &world_sid_auth, 1); - *(GetSidSubAuthority (world_sid, 0)) = SECURITY_WORLD_RID; + world_sid = (PSID) LocalAlloc (LPTR,GetSidLengthRequired (1)); + + InitializeSid (world_sid, &world_sid_auth, 1); + *(GetSidSubAuthority (world_sid, 0)) = SECURITY_WORLD_RID; + } @@ -32,2 +40,3 @@ get_world_sid () +#if 0 int @@ -169,4 +178,168 @@ get_file_attribute (const char *file, in BOOL +_set_file_attribute (const char *file, int attribute) +{ + if (os_being_run != winNT) + return TRUE; + + DWORD sidlen, domlen; + char dom[100]; + char user[256]; + SID_NAME_USE acc_type; + + struct passwd *pw = getpwuid (myself->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) %E", user); + 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) %E", domuser); + 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 (myself->gid); + PSID sidGroup = NULL; + if (grp) + { + 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) %E", grp->gr_name); + return FALSE; + } + sidGroup = (PSID) realloc (sidGroup, sidlen + 1); + debug_printf ("user: %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 %E"); + if (! SetSecurityDescriptorOwner(&sd, sidOwner, FALSE)) + debug_printf ("SetSecurityDescriptorOwner %E"); + if (sidGroup) + if (! SetSecurityDescriptorGroup(&sd, sidGroup, FALSE)) + debug_printf ("SetSecurityDescriptorGroup %E"); + + 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 3"); + return FALSE; + } + if (! InitializeAcl (acl, acl_len, ACL_REVISION)) + debug_printf ("InitializeAcl %E"); + + DWORD access = STANDARD_RIGHTS_ALL; + if (attribute & S_IRUSR) + access |= FILE_GENERIC_READ; + if (attribute & S_IWUSR) + access |= FILE_GENERIC_WRITE | FILE_DELETE_CHILD; + if (attribute & S_IXUSR) + access |= FILE_GENERIC_EXECUTE; + if (! AddAccessAllowedAce (acl, ACL_REVISION, access, sidOwner)) + debug_printf ("AddAccessAllowedAce(owner) %E"); + if (! AddAccessAllowedAce (acl, ACL_REVISION, + SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL, + get_admin_sid ())) + debug_printf ("AddAccessAllowedAce(admin) %E"); + + if (sidGroup) + { + access = 0; + if (attribute & S_IRGRP) + access |= FILE_GENERIC_READ; + if (attribute & S_IWGRP) + access |= FILE_GENERIC_WRITE | FILE_DELETE_CHILD; + if (attribute & S_IXGRP) + access |= FILE_GENERIC_EXECUTE; + if (! AddAccessAllowedAce (acl, ACL_REVISION, access, sidGroup)) + debug_printf ("AddAccessAllowedAce(group) %E"); + } + + access = 0; + if (attribute & S_IROTH) + access |= FILE_GENERIC_READ; + if (attribute & S_IWOTH) + access |= FILE_GENERIC_WRITE | FILE_DELETE_CHILD; + if (attribute & S_IXOTH) + access |= FILE_GENERIC_EXECUTE; + if (! AddAccessAllowedAce (acl, ACL_REVISION, access, get_world_sid ())) + debug_printf ("AddAccessAllowedAce(world) %E"); + + if (! SetSecurityDescriptorDacl (&sd, TRUE, acl, FALSE)) + debug_printf ("SetSecurityDescriptorDacl %E"); + + if (! SetFileSecurity (file, + OWNER_SECURITY_INFORMATION + | (sidGroup ? GROUP_SECURITY_INFORMATION : 0) + | DACL_SECURITY_INFORMATION, + &sd)) + debug_printf ("SetFileSecurity %d", GetLastError()); + + free (acl); + free (sidOwner); + free (sidGroup); + return TRUE; +} + +BOOL set_file_attribute (const char *file, int attribute) { + _set_file_attribute (file, attribute); return NTWriteEA (file, ".UNIXATTR", (char *) &attribute,