diff common/util.c @ 1118:fd85a02d771d

(issue54) Implement a privilege drop to execute the program after installation. This commit is extremly ugly as I accidentally worked in a working tree that was partially merged with default. To review the real change please check the commit that will merge this branch into default.
author Andre Heinecke <andre.heinecke@intevation.de>
date Tue, 16 Sep 2014 19:45:19 +0200
parents 1c1964c27b39 f110a3f6e387
children 2a1206932f53
line wrap: on
line diff
--- a/common/util.c	Tue Sep 16 11:45:32 2014 +0200
+++ b/common/util.c	Tue Sep 16 19:45:19 2014 +0200
@@ -16,6 +16,7 @@
 #include <grp.h>
 #include <string.h>
 #else
+#include <winsafer.h>
 #include <windows.h>
 #include <accctrl.h>
 #include <aclapi.h>
@@ -782,3 +783,72 @@
   return retval;
 }
 #endif
+
+#ifdef WIN32
+/** @brief get a restricted access token
+  *
+  * This function uses the Software Restriction API to obtain the
+  * access token for a process run als normal user.
+  *
+  * @returns A restricted handle or NULL on error.
+  */
+HANDLE
+get_restricted_token()
+{
+  SAFER_LEVEL_HANDLE user_level = NULL;
+  HANDLE retval = NULL;
+  SID_IDENTIFIER_AUTHORITY medium_identifier = {SECURITY_MANDATORY_LABEL_AUTHORITY};
+  PSID medium_sid = NULL;
+  TOKEN_MANDATORY_LABEL integrity_label;
+
+  memset (&integrity_label, 0, sizeof (integrity_label));
+
+  if (!SaferCreateLevel(SAFER_SCOPEID_USER,
+                        SAFER_LEVELID_NORMALUSER,
+                        SAFER_LEVEL_OPEN, &user_level, NULL))
+    {
+      PRINTLASTERROR ("Failed to create user level.\n");
+      return NULL;
+    }
+
+  if (!SaferComputeTokenFromLevel(user_level, NULL, &retval, 0, NULL))
+    {
+      SaferCloseLevel(user_level);
+      return NULL;
+    }
+
+  SaferCloseLevel(user_level);
+
+  /* Set the SID to medium it will still be high otherwise. Even if
+  there is no high access allowed. */
+  if (!AllocateAndInitializeSid(&medium_identifier,
+                               1,
+                               SECURITY_MANDATORY_MEDIUM_RID,
+                               0,
+                               0,
+                               0,
+                               0,
+                               0,
+                               0,
+                               0,
+                               &medium_sid))
+    {
+      PRINTLASTERROR ("Failed to initialize sid.\n");
+      return NULL;
+    }
+
+  integrity_label.Label.Attributes = SE_GROUP_INTEGRITY;
+  integrity_label.Label.Sid        = medium_sid;
+
+  if (!SetTokenInformation(retval,
+                           TokenIntegrityLevel,
+                           &integrity_label,
+                           sizeof(TOKEN_MANDATORY_LABEL)))
+    {
+      PRINTLASTERROR ("Failed to set token integrity.\n");
+      return NULL;
+    }
+
+  return retval;
+}
+#endif

http://wald.intevation.org/projects/trustbridge/