ntsec patch for setup

Pierre A. Humblet Pierre.Humblet@ieee.org
Sat Jan 11 03:37:00 GMT 2003


This is the patch mentioned in the previous e-mail. I seems
to work fine on NT and an early version was tested on 2000 (there
are differences). 

Essentially the installed files should be in the Users or 
Admins groups instead of None.
Nothing changes if the user running setup does not have the
None gid.

Pierre

2003/01/10  Pierre Humblet  <pierre.humblet@ieee.org>

	* main.cc (set_default_dacl): Replace with set_default_sec.
	(set_default_sec): Attempt to change the default group to
	Users or Administrators if it is None, in addition to setting
	Everyone in the default DACL. 
	(main): Call set_default_sec instead of set_default_dacl.
-------------- next part --------------
Index: main.cc
===================================================================
RCS file: /cvs/cygwin-apps/setup/main.cc,v
retrieving revision 2.23
diff -u -p -r2.23 main.cc
--- main.cc	25 Nov 2002 00:41:25 -0000	2.23
+++ main.cc	11 Jan 2003 02:51:08 -0000
@@ -1,4 +1,4 @@
-/*
+ /*
  * Copyright (c) 2000, Red Hat, Inc.
  *
  *     This program is free software; you can redistribute it and/or modify
@@ -78,13 +78,15 @@ static BoolOption UnattendedOption (fals
 #define iswinnt		(GetVersion() < 0x80000000)

 void
-set_default_dacl ()
+set_default_sec ()
 {
   /* To assure that the created files have a useful ACL, the
      default DACL in the process token is set to full access to
      everyone. This applies to files and subdirectories created
      in directories which don't propagate permissions to child
-     objects. */
+     objects.
+     To assure that the files group is meaningful, a token primary
+     group of None is changed to Users or Administrators. */

   /* Create a buffer which has enough room to contain the TOKEN_DEFAULT_DACL
      structure plus an ACL with one ACE. */
@@ -102,20 +104,29 @@ set_default_dacl ()
       return;
     }

-  /* Get the SID for "Everyone". */
-  PSID sid;
+  PSID esid = NULL, asid = NULL, usid = NULL;
+  HANDLE token = NULL;
+  struct {
+    PSID psid;
+    char buf[MAX_SID_LEN];
+  } gsid;
+  char lsid[MAX_SID_LEN];
+  char compname[MAX_COMPUTERNAME_LENGTH + 1];
+  char domain[MAX_COMPUTERNAME_LENGTH + 1];
+  DWORD size;
+
   SID_IDENTIFIER_AUTHORITY sid_auth = { SECURITY_WORLD_SID_AUTHORITY };
-  if (!AllocateAndInitializeSid (&sid_auth, 1, 0, 0, 0, 0, 0, 0, 0, 0, &sid))
+  if (!AllocateAndInitializeSid (&sid_auth, 1, 0, 0, 0, 0, 0, 0, 0, 0, &esid))
     {
       log (LOG_TIMESTAMP) << "AllocateAndInitializeSid() failed: " <<
 	   GetLastError () << endLog;
-      return;
+      goto out;
     }

   /* Create the ACE which grants full access to "Everyone" and store it
      in dacl->DefaultDacl. */
   if (!AddAccessAllowedAce
-      (dacl->DefaultDacl, ACL_REVISION, GENERIC_ALL, sid))
+      (dacl->DefaultDacl, ACL_REVISION, GENERIC_ALL, esid))
     {
       log (LOG_TIMESTAMP) << "AddAccessAllowedAce() failed: %lu" <<
 	   GetLastError () << endLog;
@@ -123,26 +134,125 @@ set_default_dacl ()
     }

   /* Get the processes access token. */
-  HANDLE token;
   if (!OpenProcessToken (GetCurrentProcess (),
 			 TOKEN_READ | TOKEN_ADJUST_DEFAULT, &token))
     {
-      log (LOG_TIMESTAMP) << "OpenProcessToken() failed: "
-	<< GetLastError () << endLog;
+      log (LOG_TIMESTAMP) << "OpenProcessToken() failed: " <<
+	GetLastError () << endLog;
       goto out;
     }

   /* Set the default DACL to the above computed ACL. */
   if (!SetTokenInformation (token, TokenDefaultDacl, dacl, sizeof buf))
-    log (LOG_TIMESTAMP) << "OpenProcessToken() failed: " << GetLastError ()
-      << endLog;
+    log (LOG_TIMESTAMP) << "OpenProcessToken() failed: " <<
+      GetLastError () << endLog;

-  /* Close token handle. */
-  CloseHandle (token);

-out:
-  /* Free memory occupied by the "Everyone" SID. */
-  FreeSid (sid);
+  /* Get the default group */
+  if (!GetTokenInformation (token, TokenPrimaryGroup, &gsid, sizeof gsid, &size))
+    {
+      log (LOG_TIMESTAMP) << "GetTokenInformation() failed: " <<
+	GetLastError () << endLog;
+      goto out;
+    }
+
+  /* Get the computer name */
+  if (!GetComputerName (compname, (size = sizeof compname, &size)))
+    {
+      log (LOG_TIMESTAMP) << "GetComputerName() failed: " <<
+	GetLastError () << endLog;
+      goto out;
+    }
+
+  /* Get the local domain SID */
+  SID_NAME_USE use;
+  DWORD sz;
+  if (!LookupAccountName (NULL, compname, lsid, (size = sizeof lsid, &size),
+			  domain, (sz = sizeof domain, &sz), &use))
+    {
+      log (LOG_TIMESTAMP) << "LookupAccountName() failed: " <<
+	GetLastError () << endLog;
+      goto out;
+    }
+
+  /* Create the None SID from the domain SID.
+     On NT the last subauthority of a domain is -1 and it is replaced by the RID.
+     On other systems the RID is appended. */
+  sz = *GetSidSubAuthorityCount (lsid);
+  if (*GetSidSubAuthority (lsid, sz -1) != (DWORD) -1)
+    *GetSidSubAuthorityCount (lsid) = ++sz;
+  *GetSidSubAuthority (lsid, sz -1) = DOMAIN_GROUP_RID_USERS;
+
+  /* See if the group is None */
+  if (EqualSid (gsid.psid, lsid))
+    {
+      bool isadmins = false, isusers = false;
+      sid_auth = (SID_IDENTIFIER_AUTHORITY) { SECURITY_NT_AUTHORITY };
+      /* Get the SID for "Administrators" S-1-5-32-544 */
+      if (!AllocateAndInitializeSid (&sid_auth, 2, SECURITY_BUILTIN_DOMAIN_RID,
+				     DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &asid))
+        {
+	  log (LOG_TIMESTAMP) << "AllocateAndInitializeSid() failed: " <<
+	    GetLastError () << endLog;
+	  goto out;
+	}
+      /* Get the SID for "Users" S-1-5-32-545 */
+      if (!AllocateAndInitializeSid (&sid_auth, 2, SECURITY_BUILTIN_DOMAIN_RID,
+				     DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0, &usid))
+        {
+	  log (LOG_TIMESTAMP) << "AllocateAndInitializeSid() failed: " <<
+	    GetLastError () << endLog;
+	  goto out;
+	}
+      /* Get the token groups */
+      if (!GetTokenInformation (token, TokenGroups, NULL, 0, &size)
+	  && GetLastError () != ERROR_INSUFFICIENT_BUFFER)
+        {
+	  log (LOG_TIMESTAMP) << "GetTokenInformation() failed: " <<
+	    GetLastError () << endLog;
+	  goto out;
+	}
+      else
+        {
+	  char buf[size];
+	  TOKEN_GROUPS *groups = (TOKEN_GROUPS *) buf;
+
+	  if (!GetTokenInformation (token, TokenGroups, buf, size, &size))
+	    {
+	      log (LOG_TIMESTAMP) << "GetTokenInformation() failed: " <<
+		GetLastError () << endLog;
+	      goto out;
+	    }
+	  else
+	    /* See if admins or users is present */
+	    for (DWORD pg = 0; pg < groups->GroupCount; ++pg)
+	      {
+		isadmins = isadmins || EqualSid(groups->Groups[pg].Sid, asid);
+		isusers = isusers || EqualSid(groups->Groups[pg].Sid, usid);
+	      }
+	}
+      /* Set the default group to one of the above computed SID. */
+      PSID nsid = NULL;
+      if (isusers)
+	nsid = usid;
+      else if (isadmins)
+	nsid = asid;
+      if (nsid && !SetTokenInformation (token, TokenPrimaryGroup, &nsid, sizeof nsid))
+	log (LOG_TIMESTAMP) << "SetTokenInformation() failed: " <<
+	  GetLastError () << endLog;
+    }
+ out:
+  /* Close token handle. */
+  if (token)
+    CloseHandle (token);
+
+  /* Free memory occupied by the SIDs. */
+  if (esid)
+    FreeSid (esid);
+  if (asid)
+    FreeSid (asid);
+  if (usid)
+    FreeSid (usid);
 }

 // Other threads talk to this page, so we need to have it externable.
@@ -215,10 +325,10 @@ main (int argc, char **argv)

   unattended_mode = UnattendedOption;

-  /* Set the default DACL only on NT/W2K. 9x/ME has no idea of access
-     control lists and security at all. */
+  /* Set the default DACL and Group only on NT/W2K. 9x/ME has
+     no idea of access control lists and security at all. */
   if (iswinnt)
-    set_default_dacl ();
+    set_default_sec ();

   // Initialize common controls
   InitCommonControls ();


More information about the Cygwin-apps mailing list