[Patch]: Create Global Privilege

Pierre A. Humblet pierre@phumblet.no-ip.org
Wed Nov 26 01:56:00 GMT 2003


This patch will stop the "CreateFileMapping, Win32 error 5. Terminating."
complaints.

It changes shared_name() to avoid setting the Global\ prefix on file mappings
when the Create Global Object privilege may be required but the user doesn't
have it. 

Note that when running from the console or as a service, the names are
looked up
in the global name space by default (with or without privilege), thus it
doesn't
matter if the prefix is Global\ or "". 
In other words, there is no need to determine if the user is running from 
Terminal Services.

As a side effect, the cygheap must be initialized earlier in the startup
sequence because it is needed for CloseHandle when debugging is enabled
(thus the changes in memory_init and shared_info::initialize).

I don't have access to Terminal Services to test the patch, but Fabrice
Larribe
reports that it works fine on a system where he needed, but couldn't get, the
privilege. 

Pierre

2003-11-25  Pierre Humblet <pierre.humblet@ieee.org>

	* shared.cc (shared_name): Take into account the SE_CREATE_GLOBAL_NAME
	privilege when building the name string.
	(open_shared): Remove the call to OpenFileMapping.
	(shared_info::initialize): Move cygheap initialization to ...	
	(memory_init): ... here. Suppress now useless shared_h variable.
	(user_shared_initialize): Make tu a cygpsid.
	* sec_helper.cc (set_process_privilege): Call LookupPrivilegeValue
	before opening the token.
-------------- next part --------------
Index: shared.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/shared.cc,v
retrieving revision 1.78
diff -u -p -r1.78 shared.cc
--- shared.cc	14 Nov 2003 23:40:05 -0000	1.78
+++ shared.cc	26 Nov 2003 01:37:57 -0000
@@ -35,9 +35,14 @@ char * __stdcall
 shared_name (char *ret_buf, const char *str, int num)
 {
   extern bool _cygwin_testing;
+  static const char * prefix = NULL;

-  __small_sprintf (ret_buf, "%s%s.%s.%d",
-  		   wincap.has_terminal_services () ?  "Global\\" : "",
+  if (!prefix)
+    prefix = wincap.has_terminal_services ()
+             && ( set_process_privilege (SE_CREATE_GLOBAL_NAME, true) >= 0
+		  || GetLastError () == ERROR_NO_SUCH_PRIVILEGE) ? "Global\\" : "";
+
+  __small_sprintf (ret_buf, "%s%s.%s.%d", prefix,
 		   cygwin_version.shared_id, str, num);
   if (_cygwin_testing)
     strcat (ret_buf, cygwin_version.dll_build_date);
@@ -91,15 +96,10 @@ open_shared (const char *name, int n, HA
       if (!name)
 	mapname = NULL;
       else
-	{
-	  mapname = shared_name (map_buf, name, n);
-	  shared_h = OpenFileMappingA (FILE_MAP_READ | FILE_MAP_WRITE,
-				       TRUE, mapname);
-	}
-      if (!shared_h &&
-	  !(shared_h = CreateFileMapping (INVALID_HANDLE_VALUE, psa,
+        mapname = shared_name (map_buf, name, n);
+      if (!(shared_h = CreateFileMapping (INVALID_HANDLE_VALUE, psa,
 					  PAGE_READWRITE, 0, size, mapname)))
-	api_fatal ("CreateFileMapping, %E.  Terminating.");
+	api_fatal ("CreateFileMapping %s, %E.  Terminating.", mapname);
     }

   shared = (shared_info *)
@@ -163,7 +163,7 @@ user_shared_initialize (bool reinit)
     {
       if (wincap.has_security ())
         {
-	  cygsid tu (cygheap->user.sid ());
+	  cygpsid tu (cygheap->user.sid ());
 	  tu.string (name);
 	}
       else
@@ -216,13 +216,6 @@ shared_info::initialize ()
 	low_priority_sleep (0);	// Should be hit only very very rarely
     }

-  /* Initialize the Cygwin heap, if necessary */
-  if (!cygheap)
-    {
-      cygheap_init ();
-      cygheap->user.init ();
-    }
-
   heap_init ();

   if (!sversion)
@@ -238,16 +231,21 @@ memory_init ()
 {
   getpagesize ();

+  /* Initialize the Cygwin heap, if necessary */
+  if (!cygheap)
+    {
+      cygheap_init ();
+      cygheap->user.init ();
+    }
+
   /* Initialize general shared memory */
-  HANDLE shared_h = cygheap ? cygheap->shared_h : NULL;
   cygwin_shared = (shared_info *) open_shared ("shared",
 					       CYGWIN_VERSION_SHARED_DATA,
-					       shared_h,
+					       cygheap->shared_h,
 					       sizeof (*cygwin_shared),
 					       SH_CYGWIN_SHARED);

   cygwin_shared->initialize ();
-  cygheap->shared_h = shared_h;
   ProtectHandleINH (cygheap->shared_h);

   user_shared_initialize (false);
Index: sec_helper.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/sec_helper.cc,v
retrieving revision 1.45
diff -u -p -r1.45 sec_helper.cc
--- sec_helper.cc	4 Nov 2003 15:48:18 -0000	1.45
+++ sec_helper.cc	26 Nov 2003 01:38:17 -0000
@@ -305,18 +305,18 @@ set_process_privilege (const char *privi
   int ret = -1;
   DWORD size;

+  if (!LookupPrivilegeValue (NULL, privilege, &restore_priv))
+    {
+      __seterrno ();
+      goto out;
+    }
+
   if ((use_thread
        && !OpenThreadToken (GetCurrentThread (), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
 			    0, &hToken))
       ||(!use_thread
 	 && !OpenProcessToken (hMainProc, TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
 			     &hToken)))
-    {
-      __seterrno ();
-      goto out;
-    }
-
-  if (!LookupPrivilegeValue (NULL, privilege, &restore_priv))
     {
       __seterrno ();
       goto out;


More information about the Cygwin-patches mailing list