On Wed, Feb 18, 2015 at 11:00 AM, tito <farmat...@tiscali.it> wrote: > On Wednesday 18 February 2015 09:14:42 you wrote: > >> On Wed, Feb 18, 2015 at 8:09 AM, Laszlo Papp <lp...@kde.org> wrote: > >> > On Wed, Feb 18, 2015 at 7:34 AM, Laszlo Papp <lp...@kde.org> wrote: > >> >> I thought about this, too, when writing the patch, but I rejected it >> >> because > >> >> it is not simpler, in fact more complex, it is also not the right layer >> >> for > >> >> the change. In addition, it would also be somewhat slower to execute. > >> > > >> > Just to elaborate a bit more on this as I was sending that on my phone: > >> > > >> > 1) Why do you want to make a few lines more simpler to spare a few > >> > lines to introduce bad implementation and slower operation? > >> > > >> > 2) Also, the update_passwd function already has all the structure to > >> > handle this through the file, name and member variables. It looks like > >> > the natural place to utilize the existing infrastructure. > >> > > >> > 3) Basically, you would go through the groups once in the embedded > >> > list and then you would go through again rather than just doing the > >> > thing correct in the first place at the first iteration. So basically, > >> > you would have double embedded list iteration. Even if the group list > >> > was stored in memory for _each_ user, it would still slightly be > >> > slower and I would argue that wasting memory for potentially a big > >> > file could defeat busybox's purpose in the first place. Anyway, > >> > busybox's design goal should be to be as fast as possible. Personal > >> > preferences should neither slow it down, nor make it use more memory > >> > than needed to achieve the task. > >> > >> I would actually even go further than that, namely: the same-named > >> group deletion should probably be integrated into my loop so that one > >> embedded iteration could deal with the group file changes rather than > >> two separate. > >> > > > > Hi, > > > > you can try to write a patch, but i suspect that it could be difficult > > with the current update_password interface without breaking the > > deluser from group use case. > > If you opt for doing the changes in deluser instead some useful > > get_groups code is in the id applet and could be moved to libbb as > > function. This will of course be slower as more iterations are done > > through the passwd/group files.
I start to think that the best approach would be neither to use your idea, nor mine, but actually a separate function doing the thing fast. See my updated patch below which almost works, but it remains slow if I try to inject the new code into the "line based" read and write concept. Why don't we just create a new function? commit 813e3db073aca7a55b9f3d4650055e7d1ed768b4 Author: Laszlo Papp <lp...@kde.org> 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..24f949b 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+"); @@ -159,6 +163,19 @@ int FAST_FUNC update_passwd(const char *filename, bb_perror_msg("warning: can't lock '%s'", filename); lock.l_type = F_UNLCK; + if (!name && member) { + struct group* g; + while ((g = getgrent())) { + char **s= g->gr_mem; + char **d = s; + while (*s) { + if (strcmp(*s, member)) { *d = *s; ++d; } + ++s; + } + *d = 0; + } + } + /* Read current password file, write updated /etc/passwd+ */ changed_lines = 0; while (1) { @@ -167,7 +184,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_colon || strncmp(name_colon, line, user_len) != 0) { fprintf(new_fp, "%s\n", line); goto next; } @@ -176,7 +193,7 @@ int FAST_FUNC update_passwd(const char *filename, cp = line + user_len; /* move past name: */ #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' @@ -240,7 +257,7 @@ int FAST_FUNC update_passwd(const char *filename, if (changed_lines == 0) { #if ENABLE_FEATURE_ADDUSER_TO_GROUP || ENABLE_FEATURE_DEL_USER_FROM_GROUP - if (member) { + if (name && member) { if (ENABLE_ADDGROUP && applet_name[0] == 'a') bb_error_msg("can't find %s in %s", name, filename); if (ENABLE_DELGROUP && applet_name[0] == 'd') 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; } _______________________________________________ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox