defined drop/gain privileges util functions and used it when needed
authorImran Zaman <imran.zaman@intel.com>
Wed, 20 Nov 2013 12:19:56 +0000 (14:19 +0200)
committerImran Zaman <imran.zaman@intel.com>
Wed, 20 Nov 2013 12:19:56 +0000 (14:19 +0200)
include/gum/common/gum-utils.h
src/common/gum-lock.c
src/common/gum-utils.c
src/daemon/dbus/gumd-dbus-group-adapter.c
src/daemon/dbus/gumd-dbus-server-msg-bus.c
src/daemon/dbus/gumd-dbus-server-p2p.c
src/daemon/dbus/gumd-dbus-user-adapter.c

index 66f9e47..00301eb 100644 (file)
 G_BEGIN_DECLS
 
 gchar *
-gum_generate_nonce (
+gum_utils_generate_nonce (
         GChecksumType algorithm);
 
+void
+gum_utils_drop_privileges ();
+
+void
+gum_utils_gain_privileges ();
+
 G_END_DECLS
 
 #endif  /* _GUM_UTILS_H_ */
index c5634d7..dc6d3cd 100644 (file)
@@ -31,6 +31,7 @@
 #include <sys/types.h>
 
 #include "common/gum-lock.h"
+#include "common/gum-utils.h"
 #include "common/gum-log.h"
 
 /**
@@ -76,14 +77,7 @@ gum_lock_pwdf_lock ()
         /* when run in test mode, normal user may not have privileges to get
          * the lock */
 #ifndef ENABLE_TESTS
-        DBG ("Before: ruid:%d euid:%d rgid:%d egid:%d ", getuid (), geteuid (),
-                getgid (), getegid ());
-        if (seteuid (0))
-            WARN ("seteuid(0) failed");
-        if (setegid (0))
-            WARN ("setegid(0) failed");
-        DBG ("After: ruid:%d euid:%d rgid:%d egid:%d ", getuid (), geteuid (),
-                getgid (), getegid ());
+        gum_utils_gain_privileges ();
         if (lckpwdf () < 0) {
             DBG ("pwd lock failed %s", strerror (errno));
             return FALSE;
@@ -117,14 +111,7 @@ gum_lock_pwdf_unlock ()
                DBG ("pwd unlock failed %s", strerror (errno));
                return FALSE;
            }
-            DBG ("Before: ruid:%d euid:%d rgid:%d egid:%d ", getuid (),
-                    geteuid (), getgid (), getegid ());
-           if (seteuid (getuid()))
-               WARN ("seteuid() failed");
-           if (setegid (getgid()))
-               WARN ("setegid() failed");
-            DBG ("After: ruid:%d euid:%d rgid:%d egid:%d ", getuid (),
-                    geteuid (), getgid (), getegid ());
+           gum_utils_drop_privileges ();
 #endif
        }
     } else if (lock_count <= 0) {
index 6eac8c6..9e468ac 100644 (file)
@@ -84,7 +84,7 @@ init_exit:
 }
 
 /**
- * gum_generate_nonce:
+ * gum_utils_generate_nonce:
  * @algorithm: the #GChecksumType algorithm
  *
  * Generates nonce based on hashing algorithm as specified in @algorithm
@@ -92,7 +92,7 @@ init_exit:
  * Returns: (transfer full): generate nonce if successful, NULL otherwise.
  */
 gchar *
-gum_generate_nonce (
+gum_utils_generate_nonce (
         GChecksumType algorithm)
 {
     GHmac *hmac;
@@ -125,3 +125,32 @@ nonce_exit:
     return nonce;
 }
 
+/**
+ * gum_utils_drop_privileges:
+ *
+ * Drops the privileges for the calling process. Effective uid is to real uid.
+ *
+ */
+void
+gum_utils_drop_privileges ()
+{
+    DBG ("Before set: r-uid %d e-uid %d", getuid (), geteuid ());
+    if (seteuid (getuid()))
+        WARN ("seteuid() failed");
+    DBG ("After set: r-uid %d e-uid %d", getuid (), geteuid ());
+}
+
+/**
+ * gum_utils_gain_privileges:
+ *
+ * Gains the privileges for the calling process. Effective uid is to 0.
+ *
+ */
+void
+gum_utils_gain_privileges ()
+{
+    DBG ("Before set: r-uid %d e-uid %d", getuid (), geteuid ());
+    if (seteuid (0))
+        WARN ("seteuid() failed");
+    DBG ("After set: r-uid %d e-uid %d", getuid (), geteuid ());
+}
index 0105c12..31e4d14 100644 (file)
@@ -458,7 +458,7 @@ gumd_dbus_group_adapter_new_with_connection (
     _sync_group_properties (G_OBJECT (adapter->priv->group),
             G_OBJECT (adapter->priv->dbus_group));
 
-    nonce = gum_generate_nonce (G_CHECKSUM_SHA1);
+    nonce = gum_utils_generate_nonce (G_CHECKSUM_SHA1);
     object_path = g_strdup_printf ("%s/Group_%s_%d",
             GUM_GROUP_SERVICE_OBJECTPATH, nonce, object_counter++);
     g_free (nonce);
index 3143e9c..b88c5b3 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "config.h"
 #include "common/gum-dbus.h"
+#include "common/gum-utils.h"
 #include "common/gum-log.h"
 #include "common/gum-defines.h"
 
@@ -160,12 +161,24 @@ _on_name_acquired (
     g_object_weak_ref (G_OBJECT (server->priv->group_service),
             _on_group_interface_dispose, server);
 
-    DBG ("Before: real uid %d effective uid %d", getuid (), geteuid ());
-    if (seteuid (getuid()))
-        WARN ("seteuid() failed");
-    if (setegid (getgid()))
-        WARN ("setegid() failed");
-    DBG ("After: real gid %d effective gid %d", getgid (), getegid ());
+    /* In case of session bus, privileges are dropped in the daemon start phase
+     * as it is not needed. Besides in order for session bus to work, effective
+     * uid/gid should be same as real uid/gid as 'set-user bit on execution(s)'
+     * is set on the daemon binary.
+     *
+     * In case of system bus, privileges are dropped when bus name is acquired
+     * rather than at the daemon start phase as dbus does not allow daemon to
+     * connect if the privileges are dropped earlier.
+     *
+     * In case of p2p, privileges are dropped in the daemon start phase as it is
+     * not needed.
+     *
+     * In all cases once connected, privileges are gained and dropped on
+     * need basis
+     * */
+    if (GUM_BUS_TYPE == G_BUS_TYPE_SYSTEM) {
+        gum_utils_drop_privileges ();
+    }
 }
 
 static void
@@ -261,6 +274,10 @@ _gumd_dbus_server_msg_bus_start (
     DBG("Start MSG-BUS Dbus server for bus type %s",
             GUM_BUS_TYPE == G_BUS_TYPE_SYSTEM? "SYSTEM":"SESSION");
 
+    if (GUM_BUS_TYPE == G_BUS_TYPE_SESSION) {
+        gum_utils_drop_privileges ();
+    }
+
     GumdDbusServerMsgBus *server = GUMD_DBUS_SERVER_MSG_BUS (self);
     server->priv->name_owner_id = g_bus_own_name (GUM_BUS_TYPE,
             GUM_SERVICE,
index bca9afe..a451a29 100644 (file)
@@ -30,6 +30,7 @@
 #include <sys/socket.h>
 
 #include "common/gum-dbus.h"
+#include "common/gum-utils.h"
 #include "common/gum-log.h"
 #include "common/gum-defines.h"
 
@@ -503,6 +504,23 @@ gumd_dbus_server_p2p_new_with_address (
 GumdDbusServerP2P *
 gumd_dbus_server_p2p_new ()
 {
+    /* In case of session bus, privileges are dropped in the daemon start phase
+     * as it is not needed. Besides in order for session bus to work, effective
+     * uid/gid should be same as real uid/gid as 'set-user bit on execution(s)'
+     * is set on the daemon binary.
+     *
+     * In case of system bus, privileges are dropped when bus name is acquired
+     * rather than at the daemon start phase as dbus does not allow daemon to
+     * connect if the privileges are dropped earlier.
+     *
+     * In case of p2p, privileges are dropped in the daemon start phase as it is
+     * not needed.
+     *
+     * In all cases once connected, privileges are gained and dropped on
+     * need basis
+     * */
+    gum_utils_drop_privileges ();
+
     gchar *address = g_strdup_printf (GUM_DBUS_ADDRESS,
             g_get_user_runtime_dir());
     GumdDbusServerP2P *server = gumd_dbus_server_p2p_new_with_address (
index 119a14d..7ba9f5d 100644 (file)
@@ -388,7 +388,7 @@ gumd_dbus_user_adapter_new_with_connection (
     _sync_user_properties (G_OBJECT (adapter->priv->user),
             G_OBJECT (adapter->priv->dbus_user));
 
-    nonce = gum_generate_nonce (G_CHECKSUM_SHA1);
+    nonce = gum_utils_generate_nonce (G_CHECKSUM_SHA1);
     object_path = g_strdup_printf ("%s/User_%s_%d",
             GUM_USER_SERVICE_OBJECTPATH, nonce, object_counter++);
     g_free (nonce);