www.delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin-developers/1999/01/22/19:54:34

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
To: Sergey Okhapkin <sos AT prospect DOT com DOT ru>
Cc: "cygwin32-developers AT cygnus DOT com" <cygwin32-developers AT cygnus DOT com>,
Christopher Faylor <cgf AT cygnus DOT com>

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 <unistd.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 #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,

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019