www.delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin-developers/1999/01/22/05:21:07

From: corinna DOT vinschen AT cityweb DOT de (Corinna Vinschen)
Subject: Patch: UNIX-like permissions on objects
22 Jan 1999 05:21:07 -0800 :
Message-ID: <36A877AA.9ABB8AD1.cygnus.cygwin32.developers@cityweb.de>
Mime-Version: 1.0
To: cygwin32-developers AT cygnus DOT com

Hi all,

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.

The functions are able, to substitute the global variables
`sec_none' and `sec_none_nih'. Using this functions
for example `in sigproc::getsem()' enables admin, to kill
processes of every user and to kill processes, started via
SRVANY, which have done a setsid(), e.g. if the service
database starts `inetd' without option `-d'. This wasn't
possible 'til now.

The SECURITY_ATTRIBUTES, which are needed twice for every user,
(inheritable and not inheritable) are generated only once, when
a user process calls this functions the first time. They are not
duplicated on process creation, but `static NO_COPY' in the DLL,
to save time and memory.

To get the administrators or administrators group SID, the
/etc/group and /etc/passwd files are searched for

1st:   gid 544, if not found
2nd:   uid 544, if not found
3rd:   uid 500, if not found
4th:   try the fixed string "administrator".

I have done this, because the name of the administrators group is
not the same in the different native language versions of WinNT.

It shouldn't be unmentioned that the above method, for getting the
admins group name, is a security leak! I have created this, because
I wished to login as another user than admin, but want to have their
permissions so far as it affects cygwin. The code would be easy to
shorten, if this is not acceptable.

The used structure `sa_user' saves the name of the user, for later
checks. Another facility would be, to save the uid instead of the
name, to speed up the initial `for'-loop. This would be easy to do.

The patch affects only shared.cc and shared.h, but for testing
purposes, I have changed the call to CreateSemaphore() in 
`sigproc.cc:getsem()', too. I have attached it.
Nevertheless, the functions `sec_user()' and `sec_user_nih()' would
be usefull on any windows-object creation.

I would be glad, to here your opinions about this patch.

BTW: The patch is against winsup-19990101, but this should be
all one, because it's not affecting existing code.


Regards,
Corinna


ChangeLog:
==========

21 Jan 12:30:00 1999  Corinna Vinschen  <corinna DOT vinschen AT cityweb DOT de>

	* sigproc.cc (getsem): CreateSemaphore calls sec_user_nih()
	instead of using sec_none_nih.

	* shared.h: Prototypes for the above functions.

	* shared.cc: New functions `sec_user()' and `sec_user_nih()'.
	New function `get_admin_sid()' as static helper function.

Index: sigproc.cc
===================================================================
RCS file: /src/cvsroot/winsup-981230/sigproc.cc,v
retrieving revision 1.2
diff -u -p -b -1 -r1.2 sigproc.cc
--- sigproc.cc  1998/12/31 13:27:54     1.2
+++ sigproc.cc  1999/01/22 12:23:38
@@ -1070,3 +1070,3 @@ getsem (pinfo *p, const char *str, int i
       DWORD winpid = GetCurrentProcessId ();
-      h = CreateSemaphore (&sec_none_nih, init, max, str = shared_name (str, winpid));
+      h = CreateSemaphore (sec_user_nih (), init, max, str = shared_name (str, winpid));
       p = myself;
Index: shared.h
===================================================================
RCS file: /src/cvsroot/winsup-981230/shared.h,v
retrieving revision 1.1.1.1
diff -u -p -b -1 -r1.1.1.1 shared.h
--- shared.h    1998/12/30 23:01:58     1.1.1.1
+++ shared.h    1999/01/22 12:06:16
@@ -395,2 +395,4 @@ public:
 extern SECURITY_ATTRIBUTES sec_none, sec_none_nih, sec_all, sec_all_nih;
+extern SECURITY_ATTRIBUTES *sec_user (BOOL inherit = TRUE);
+extern SECURITY_ATTRIBUTES *sec_user_nih ();

Index: shared.cc
===================================================================
RCS file: /src/cvsroot/winsup-981230/shared.cc,v
retrieving revision 1.1.1.1
diff -u -p -b -1 -r1.1.1.1 shared.cc
--- shared.cc   1998/12/30 23:01:58     1.1.1.1
+++ shared.cc   1999/01/22 12:06:58
@@ -12,2 +12,5 @@ details. */
 #include <stdio.h>
+#include <stdlib.h>
+#include <grp.h>
+#include <pwd.h>
 #include "winsup.h"
@@ -187,2 +190,154 @@ SECURITY_DESCRIPTOR *get_null_sd ()
   return null_sdp;
+}
+
+static PSID
+get_admin_sid ()
+{
+  static NO_COPY PSID sidBuf;
+
+  if (! sidBuf)
+    {
+      struct group *gr_ptr;
+      struct passwd *pw_ptr;
+      char user[32], dom[100];
+      DWORD sidlen, domlen;
+      SID_NAME_USE acc_type;
+
+      sidBuf = (PSID) malloc (1024);
+
+      // Get name of administrator group from /etc/group
+
+      if ((gr_ptr = getgrgid (544)) != NULL
+          && strcmp (gr_ptr->gr_name, "everyone"))
+        strcpy (user, gr_ptr->gr_name);
+
+      // else get name of administrator group from /etc/passwd
+
+      else if ((pw_ptr = getpwuid (544)) != NULL)
+        strcpy (user, pw_ptr->pw_name);
+
+      // else get name of administrator from /etc/passwd
+
+      else if ((pw_ptr = getpwuid (500)) != NULL)
+        strcpy (user, pw_ptr->pw_name);
+
+      // else try "administrator"
+
+      else
+        strcpy (user, "administrator");
+
+      if (! LookupAccountName (NULL, user,
+                               sidBuf, (sidlen = 1024, &sidlen),
+                               dom, (domlen = 100, &domlen),
+                               &acc_type))
+        {
+          free (sidBuf);
+          sidBuf = NULL;
+        }
+      else
+        sidBuf = (PSID) realloc (sidBuf, sidlen + 1);
+    }
+  return sidBuf;
+}
+
+struct user_sa {
+  char                user[32];
+  SECURITY_ATTRIBUTES sa;
+  SECURITY_ATTRIBUTES sa_nih;
+  SECURITY_DESCRIPTOR sd;
+  PACL                acl;
+};
+
+static NO_COPY int sa_cnt = 0;
+static NO_COPY user_sa *sa_list;
+
+SECURITY_ATTRIBUTES *
+sec_user (BOOL inherit)
+{
+  for (int i = 0; i < sa_cnt; ++i)
+    if (! strcmp (sa_list[i].user, getlogin ()))
+      return inherit ? &sa_list[i].sa_nih : &sa_list[i].sa;
+
+  PSID sidBuf;
+
+  sidBuf = (PSID) malloc (1024);
+  if (! sidBuf)
+    return inherit ? &sec_none_nih : &sec_none;
+
+  DWORD sidlen, domlen;
+  char dom[100];
+  SID_NAME_USE acc_type;
+
+  if (! LookupAccountName (NULL, getlogin (),
+                          sidBuf, (sidlen = 1024, &sidlen),
+                          dom, (domlen = 100, &domlen),
+                          &acc_type))
+    {
+      free (sidBuf);
+      return inherit ? &sec_none_nih : &sec_none;
+    }
+  else if (acc_type != SidTypeUser)
+    {
+      char domuser[356];
+      strcpy (domuser, dom);
+      strcat (domuser, "\\");
+      strcpy (domuser, getlogin ());
+      if (! LookupAccountName (NULL, domuser,
+                              sidBuf, (sidlen = 1024, &sidlen),
+                              dom, (domlen = 100, &domlen),
+                              &acc_type))
+       {
+         free (sidBuf);
+         return inherit ? &sec_none_nih : &sec_none;
+       }
+    }
+  sidBuf = (PSID) realloc (sidBuf, sidlen + 1);
+
+  size_t acl_len = sizeof (ACL)
+                   + 2 * (sizeof (ACCESS_ALLOWED_ACE) - sizeof (DWORD))
+                  + GetLengthSid (sidBuf)
+                  + GetLengthSid (get_admin_sid ());
+  PACL acl = (PACL) malloc (acl_len);
+  if (! acl)
+    {
+      free (sidBuf);
+      return inherit ? &sec_none_nih : &sec_none;
+    }
+  InitializeAcl (acl, acl_len, ACL_REVISION);
+  AddAccessAllowedAce (acl, ACL_REVISION,
+                       SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL,
+                      sidBuf);
+  AddAccessAllowedAce (acl, ACL_REVISION,
+                       SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL,
+                      get_admin_sid ());
+
+  user_sa *tmp_sa_list = (user_sa *) realloc (sa_list,
+                                              (sa_cnt + 1) * sizeof (user_sa));
+  if (! tmp_sa_list)
+    {
+      free (acl);
+      free (sidBuf);
+      return inherit ? &sec_none_nih : &sec_none;
+    }
+  sa_list = tmp_sa_list;
+
+  sa_list[sa_cnt].acl = acl;
+  InitializeSecurityDescriptor (&sa_list[sa_cnt].sd,
+                                SECURITY_DESCRIPTOR_REVISION);
+  SetSecurityDescriptorDacl (&sa_list[sa_cnt].sd, TRUE, acl, FALSE);
+  sa_list[sa_cnt].sa.nLength =
+  sa_list[sa_cnt].sa_nih.nLength = sizeof (SECURITY_ATTRIBUTES);
+  sa_list[sa_cnt].sa.lpSecurityDescriptor =
+  sa_list[sa_cnt].sa_nih.lpSecurityDescriptor = &sa_list[sa_cnt].sd;
+  sa_list[sa_cnt].sa.bInheritHandle = TRUE;
+  sa_list[sa_cnt].sa_nih.bInheritHandle = FALSE;
+  strcpy (sa_list[sa_cnt].user, getlogin ());
+  ++sa_cnt;
+  return inherit ? &sa_list[sa_cnt - 1].sa : &sa_list[sa_cnt - 1].sa_nih;
+}
+
+SECURITY_ATTRIBUTES *
+sec_user_nih ()
+{
+  return sec_user (FALSE);
 }

- Raw text -


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