[lib/privs] Changing user IDs should be done before dropping privileges

2006-03-14 Paul Jakma <paul.jakma@sun.com>

	* privs.c: (zprivs_caps_init) Change user IDs before lowering
	  privileges, while this seems to work on Linux, on Solaris
	  it rightfully refuses due to PRIV_PROC_SETID having been
	  dropped.
diff --git a/lib/ChangeLog b/lib/ChangeLog
index 34c79e4..8794d69 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,10 @@
+2006-03-14 Paul Jakma <paul.jakma@sun.com>
+
+	* privs.c: (zprivs_caps_init) Change user IDs before lowering
+	  privileges, while this seems to work on Linux, on Solaris
+	  it rightfully refuses due to PRIV_PROC_SETID having been
+	  dropped.
+
 2006-03-06 Paul Jakma <paul.jakma@sun.com>
 
 	* if.h: export show_address_cmd, for anyone who wishes to use
diff --git a/lib/privs.c b/lib/privs.c
index 8ed39f4..f4117e2 100644
--- a/lib/privs.c
+++ b/lib/privs.c
@@ -249,13 +249,6 @@
                        "but no capabilities supplied\n");
     }
 
-  if ( !(zprivs_state.caps = cap_init()) )
-    {
-      fprintf (stderr, "privs_init: failed to cap_init, %s\n", 
-               safe_strerror (errno));
-      exit (1);
-    }
-
   /* we have caps, we have no need to ever change back the original user */
   if (zprivs_state.zuid)
     {
@@ -267,6 +260,13 @@
         }
     }
   
+  if ( !(zprivs_state.caps = cap_init()) )
+    {
+      fprintf (stderr, "privs_init: failed to cap_init, %s\n", 
+               safe_strerror (errno));
+      exit (1);
+    }
+
   if ( cap_clear (zprivs_state.caps) )
     {
       fprintf (stderr, "privs_init: failed to cap_clear, %s\n", 
@@ -483,6 +483,19 @@
   /* need either valid or empty sets for both p and i.. */
   assert (zprivs_state.syscaps_i && zprivs_state.syscaps_p);
   
+  /* we have caps, we have no need to ever change back the original user
+   * change real, effective and saved to the specified user.
+   */
+  if (zprivs_state.zuid)
+    {
+      if ( setreuid (zprivs_state.zuid, zprivs_state.zuid) )
+        {
+          fprintf (stderr, "%s: could not setreuid, %s\n", 
+                   __func__, safe_strerror (errno));
+          exit (1);
+        }
+    }
+  
   /* set the permitted set */
   if (setppriv (PRIV_SET, PRIV_PERMITTED, zprivs_state.syscaps_p))
     {
@@ -499,17 +512,6 @@
       exit (1);
     }
 
-  /* we have caps, we have no need to ever change back the original user */
-  if (zprivs_state.zuid)
-    {
-      if ( setreuid (zprivs_state.zuid, zprivs_state.zuid) )
-        {
-          fprintf (stderr, "%s: could not setreuid, %s\n", 
-                   __func__, safe_strerror (errno));
-          exit (1);
-        }
-    }
-  
   /* now clear the effective set and we're ready to go */
   if (setppriv (PRIV_SET, PRIV_EFFECTIVE, empty))
     {