From 3ad37a682dea0cce4e0b10a0a83ecae100bd3325 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= <fpeters@0d.be>
Date: Fri, 18 Mar 2011 11:18:00 +0100
Subject: [PATCH 2/2] create and manage groups like on a debian system

---
 src/daemon.c |   27 +++++++++++++--------------
 src/user.c   |   24 +++++++++++++-----------
 src/util.c   |   42 ++++++++++++++++++++++++++++++++++++++++++
 src/util.h   |    9 +++++++++
 4 files changed, 77 insertions(+), 25 deletions(-)

diff --git a/src/daemon.c b/src/daemon.c
index a32276b..54e4b7d 100644
--- a/src/daemon.c
+++ b/src/daemon.c
@@ -1107,20 +1107,8 @@ daemon_create_user_authorized_cb (Daemon                *daemon,
         argv[1] = "-m";
         argv[2] = "-c";
         argv[3] = cd->real_name;
-        if (cd->account_type == ACCOUNT_TYPE_ADMINISTRATOR) {
-                argv[4] = "-G";
-                argv[5] = "wheel";
-                argv[6] = cd->user_name;
-                argv[7] = NULL;
-        }
-        else if (cd->account_type == ACCOUNT_TYPE_STANDARD) {
-                argv[6] = cd->user_name;
-                argv[7] = NULL;
-        }
-        else {
-                throw_error (context, ERROR_FAILED, "Don't know how to add user of type %d", cd->account_type);
-                return;
-        }
+        argv[4] = cd->user_name;
+        argv[5] = NULL;
 
         error = NULL;
         if (!spawn_with_login_uid (context, argv, &error)) {
@@ -1129,6 +1117,17 @@ daemon_create_user_authorized_cb (Daemon                *daemon,
                 return;
         }
 
+        if (cd->account_type == ACCOUNT_TYPE_ADMINISTRATOR) {
+                add_user_to_group (context, cd->user_name, "admin");
+        }
+        if (cd->account_type == ACCOUNT_TYPE_ADMINISTRATOR ||
+            cd->account_type == ACCOUNT_TYPE_STANDARD) {
+                add_user_to_group (context, cd->user_name, "audio");
+                add_user_to_group (context, cd->user_name, "cdrom");
+                add_user_to_group (context, cd->user_name, "dialout");
+                add_user_to_group (context, cd->user_name, "plugdev");
+        }
+
         user = daemon_local_find_user_by_name (daemon, cd->user_name);
 
         dbus_g_method_return (context, user_local_get_object_path (user));
diff --git a/src/user.c b/src/user.c
index 738b0d3..b9719ee 100644
--- a/src/user.c
+++ b/src/user.c
@@ -412,7 +412,7 @@ static gint
 account_type_from_pwent (struct passwd *pwent)
 {
         struct group *grp;
-        gid_t wheel;
+        gid_t admin;
         gid_t *groups;
         gint ngroups;
         gint i;
@@ -422,18 +422,20 @@ account_type_from_pwent (struct passwd *pwent)
                 return ACCOUNT_TYPE_ADMINISTRATOR;
         }
 
-        grp = getgrnam ("wheel");
+        grp = getgrnam ("admin");
         if (grp == NULL) {
-                g_debug ("wheel group not found");
+                g_debug ("admin group not found");
                 return ACCOUNT_TYPE_STANDARD;
         }
-        wheel = grp->gr_gid;
+        admin = grp->gr_gid;
 
         ngroups = get_user_groups (pwent->pw_name, pwent->pw_gid, &groups);
 
         for (i = 0; i < ngroups; i++) {
-                if (groups[i] == wheel)
+                if (groups[i] == admin) {
+                        g_free (groups);
                         return ACCOUNT_TYPE_ADMINISTRATOR;
+                }
         }
 
         g_free (groups);
@@ -1584,7 +1586,7 @@ user_change_account_type_authorized_cb (Daemon                *daemon,
         gid_t *groups;
         gint ngroups;
         GString *str;
-        gid_t wheel;
+        gid_t admin;
         struct group *grp;
         gint i;
         gchar *argv[5];
@@ -1594,24 +1596,24 @@ user_change_account_type_authorized_cb (Daemon                *daemon,
                          "change account type of user '%s' (%d) to %d",
                          user->user_name, user->uid, account_type);
 
-                grp = getgrnam ("wheel");
+                grp = getgrnam ("admin");
                 if (grp == NULL) {
-                        throw_error (context, ERROR_FAILED, "failed to set account type: wheel group not found");
+                        throw_error (context, ERROR_FAILED, "failed to set account type: admin group not found");
                         return;
                 }
-                wheel = grp->gr_gid;
+                admin = grp->gr_gid;
 
                 ngroups = get_user_groups (user->user_name, user->gid, &groups);
 
                 str = g_string_new ("");
                 for (i = 0; i < ngroups; i++) {
-                        if (groups[i] == wheel)
+                        if (groups[i] == admin)
                                 continue;
                         g_string_append_printf (str, "%d,", groups[i]);
                 }
                 switch (account_type) {
                 case ACCOUNT_TYPE_ADMINISTRATOR:
-                        g_string_append_printf (str, "%d", wheel);
+                        g_string_append_printf (str, "%d", admin);
                         break;
                 default:
                         /* remove excess comma */
diff --git a/src/util.c b/src/util.c
index 7f044f4..f933761 100644
--- a/src/util.c
+++ b/src/util.c
@@ -282,3 +282,45 @@ get_caller_uid (DBusGMethodInvocation *context, gint *uid)
 
         return TRUE;
 }
+
+void
+add_user_to_group (DBusGMethodInvocation *context,
+                  const char *user_name,
+                  const char *group_name)
+{
+        GError *error;
+        gchar *argv[4];
+
+        argv[0] = (gchar*) "/usr/sbin/adduser";
+        argv[1] = (gchar*) user_name;
+        argv[2] = (gchar*) group_name;
+        argv[3] = NULL;
+
+        error = NULL;
+        if (!spawn_with_login_uid (context, argv, &error)) {
+                g_warning ("failed to add user %s to group %s", user_name, group_name);
+                g_error_free (error);
+                return;
+        }
+}
+
+void
+remove_user_from_group (DBusGMethodInvocation *context,
+                        const char *user_name,
+                        const char *group_name)
+{
+        GError *error;
+        gchar *argv[4];
+
+        argv[0] = (gchar*) "/usr/sbin/deluser";
+        argv[1] = (gchar*) user_name;
+        argv[2] = (gchar*) group_name;
+        argv[3] = NULL;
+
+        error = NULL;
+        if (!spawn_with_login_uid (context, argv, &error)) {
+                g_warning ("failed to remove user %s from group %s", user_name, group_name);
+                g_error_free (error);
+                return;
+        }
+}
diff --git a/src/util.h b/src/util.h
index bfdf780..323e858 100644
--- a/src/util.h
+++ b/src/util.h
@@ -41,6 +41,15 @@ gint get_user_groups (const gchar  *username,
                       gid_t         group,
                       gid_t       **groups);
 
+void add_user_to_group (DBusGMethodInvocation *context,
+                        const char *user_name,
+                        const char *group_name);
+
+void remove_user_from_group (DBusGMethodInvocation *context,
+                             const char *user_name,
+                             const char *group_name);
+
+
 G_END_DECLS
 
 #endif /* __UTIL_H__ */
-- 
1.7.4.1

