Bug in the deluser applet

Laszlo Papp lpapp at kde.org
Tue Feb 17 20:05:57 UTC 2015


WARNING: this is pseudo code. Do not use it as is. It makes my
/etc/group empty after the run, but it ought to show the concept I am
thinking of. As indicated, the implementation has some bug currently.
Any feedback is welcome.

commit d7075bb9195a65d11b43f516112f5b0134cbc62a
Author: Laszlo Papp <laszlo.papp at polatis.com>
Date:   Tue Feb 17 20:01:04 2015 +0000

    Delete the user from all the groups for user deletion

diff --git a/libbb/update_passwd.c b/libbb/update_passwd.c
index a30af6f..f280813 100644
--- a/libbb/update_passwd.c
+++ b/libbb/update_passwd.c
@@ -62,6 +62,8 @@ static void check_selinux_update_passwd(const char *username)
     only if CONFIG_PASSWD=y and applet_name[0] == 'p' like in passwd
     or if CONFIG_CHPASSWD=y and applet_name[0] == 'c' like in chpasswd

+ 8) delete a user from all groups : update_passwd(FILE, NULL, NULL, MEMBER)
+
  This function does not validate the arguments fed to it
  so the calling program should take care of that.

@@ -81,7 +83,7 @@ int FAST_FUNC update_passwd(const char *filename,
        FILE *new_fp;
        char *fnamesfx;
        char *sfx_char;
-       char *name_colon;
+       char *name_colon = 0;
        unsigned user_len;
        int old_fd;
        int new_fd;
@@ -99,13 +101,15 @@ int FAST_FUNC update_passwd(const char *filename,
        if (filename == NULL)
                return ret;

-       check_selinux_update_passwd(name);
+       if (name) check_selinux_update_passwd(name);

        /* New passwd file, "/etc/passwd+" for now */
        fnamesfx = xasprintf("%s+", filename);
        sfx_char = &fnamesfx[strlen(fnamesfx)-1];
-       name_colon = xasprintf("%s:", name);
-       user_len = strlen(name_colon);
+    if (name) {
+        name_colon = xasprintf("%s:", name);
+        user_len = strlen(name_colon);
+    }

        if (shadow)
                old_fp = fopen(filename, "r+");
@@ -167,7 +171,7 @@ int FAST_FUNC update_passwd(const char *filename,
                line = xmalloc_fgetline(old_fp);
                if (!line) /* EOF/error */
                        break;
-               if (strncmp(name_colon, line, user_len) != 0) {
+               if (name && strncmp(name_colon, line, user_len) != 0) {
                        fprintf(new_fp, "%s\n", line);
                        goto next;
                }
@@ -175,8 +179,21 @@ int FAST_FUNC update_passwd(const char *filename,
                /* We have a match with "name:"... */
                cp = line + user_len; /* move past name: */

+        if (!name && member) {
+            struct group* g;
+            while ((g = getgrent())) {
+                char **s= g->gr_mem;
+                char **d = s;
+                while (s && *s) {
+                    if (strcmp(*s, member)) { *d = *s; ++d; }
+                    ++s;
+                }
+                *d = 0;
+            }
+        }
+
 #if ENABLE_FEATURE_ADDUSER_TO_GROUP || ENABLE_FEATURE_DEL_USER_FROM_GROUP
-               if (member) {
+        if (name && member) {
                        /* It's actually /etc/group+, not /etc/passwd+ */
                        if (ENABLE_FEATURE_ADDUSER_TO_GROUP
                         && applet_name[0] == 'a'
diff --git a/loginutils/deluser.c b/loginutils/deluser.c
index 01a9386..8219569 100644
--- a/loginutils/deluser.c
+++ b/loginutils/deluser.c
@@ -82,6 +82,9 @@ int deluser_main(int argc, char **argv)
  do_delgroup:
                        /* "delgroup GROUP" or "delgroup USER GROUP" */
                        if (do_deluser < 0) { /* delgroup after deluser? */
+                           pfile = bb_path_group_file;
+                if (update_passwd(pfile, NULL, NULL, name) == -1)
+                    return EXIT_FAILURE;
                                gr = getgrnam(name);
                                if (!gr)
                                        return EXIT_SUCCESS;
@@ -99,7 +102,6 @@ int deluser_main(int argc, char **argv)
                                }
                                //endpwent();
                        }
-                       pfile = bb_path_group_file;
                        if (ENABLE_FEATURE_SHADOWPASSWDS)
                                sfile = bb_path_gshadow_file;
                }


More information about the busybox mailing list