User Management / delete user from group

120 views
Skip to first unread message

Bob

unread,
Apr 29, 2013, 6:58:59 PM4/29/13
to help-c...@googlegroups.com
I have been struggling to solve this problem and suspect I am going to have to write a perl script, but I want to ask some people with more experience than myself.

I define a set of users who I want cfengine to add to the system, similar to what is done in the "Learning CFEngine" Book:

vars:
  "users[bob][gecos]"  string => "Bob,,,,";
  "users[bob][group]"  string => "users";
  "users[bob][groups]" string => "sudo,adm,staff";
  "users[bob][shell]"  string => "/bin/bash";

  "etc_group" slist => readstringlist("/tmp/group", "\s*#.*",
                                      "\n", 32767, 10240);


Now let's say I want to remove "bob" from sudo and adm at a future date. My idea was to read /etc/group, then grep for user "bob" to determine which groups the user is currently a member:

methods:
  "users" usebundle => check_user_groups("example.users",
                                         "example.etc_group");

bundle agent check_user_groups(info,sys_groups)
{
vars:
  "user" slist => getindices("$(info)");
  "sys_groups_$(user)" slist => grep(".*$(user).*", "$(sys_groups)");
}

The trouble I am having is now I have a list of groups for which the user is a member, but there is extra information I cannot remove:

adm:x:4:bob
sudo:x:27:bob,ray
staff:x:50:bob,jim


I'd appreciate suggestions before I have to write a perl script. Thank you.


Brian Bennett

unread,
Apr 30, 2013, 2:19:03 AM4/30/13
to Bob, help-c...@googlegroups.com
This seems like it could easily be done with a replace_patterns promise.

Here's an untested edit_line bundle:

bundle edit_line remove_user_from_group (user,group) {

replace_patterns:

# This uses a zero width positive look behind assertion to make sure
# that the proper group is matched but is not part of the pattern
# being replaced.

"(?<=$(group).*)($(user))"
replace_with => value(""),
comment => "Remove user as only member";
"(?<=$(group).*)(,$(user))"
replace_with => value(""),
comment => "Remove user at end of list";
"(?<=$(group).*)($(user),)"
replace_with => value(""),
comment => "Remove user at beginning of list";
"(?<=$(group).*)(,$(user),)"
replace_with => value(","),
comment => "Remove user in middle of list";
}

I don't have time to test this right now, but if someone wants to give it a try, and it works, I'll open a pull request to add it to cfengine_stdlib.cf.

--
Brian
> --
> You received this message because you are subscribed to the Google Groups "help-cfengine" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to help-cfengin...@googlegroups.com.
> To post to this group, send email to help-c...@googlegroups.com.
> Visit this group at http://groups.google.com/group/help-cfengine?hl=en.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>


--
Brian

Bob

unread,
Apr 30, 2013, 9:55:48 AM4/30/13
to help-c...@googlegroups.com, Bob
Thanks for your response and consideration. If I understand your solution correctly, it assumes I know which groups from which the user should be removed. That is the portion I am struggling with now, once I solve that problem your solution will help me edit /etc/group, correct?

Brian Bennett

unread,
Apr 30, 2013, 11:26:23 AM4/30/13
to Bob, help-c...@googlegroups.com, Bob
Remember that CFEngine uses pcre everywhere. You can specify the group as .* and they'll be removed from all groups. Here's an example:

    bundle agent user_cleanup {
      vars:
        "former_employees" slist => { "eve", "malory" };
      files:
        edit_line => remove_user_from_group("$(former_employees)", ".*");
    }

Again, I haven't tested this.

-- 
Brian

jon.k...@gmail.com

unread,
Jan 3, 2017, 5:24:13 AM1/3/17
to help-cfengine
PCRE look behind won't work here, but try the \K assertion:

bundle agent playground(class)

{
    vars:
        "former_employees" slist         => { "eve", "malory" };
        "group" string                => "adm";
        "file_name" string            => "/etc/group";

    files:
            "$(file_name)"
                edit_line    => remove_user_from_group("$(former_employees)", "$(group)");

}

bundle edit_line remove_user_from_group (user,group)
{
    replace_patterns:
        "($(group).*)\K(,$(user))"

            replace_with        => value(""),
            comment            => "Remove user at end of list";
        "($(group).*)\K($(user),)"

            replace_with        => value(""),
            comment            => "Remove user at beginning of list";
        "($(group).*)\K($(user))"

            replace_with        => value(""),
            comment            => "Remove user as only member";
}

$(group) may be .*

Jon

jon.k...@gmail.com

unread,
Jan 3, 2017, 6:19:27 AM1/3/17
to help-cfengine
Thinking about it, a pattern like this (notice the colon after the $(group):

    replace_patterns:
        "($(group):.*)\K(,$(user))"

            replace_with        => value(""),
            comment            => "Remove user at end of list";
        "($(group):.*)\K($(user),)"

            replace_with        => value(""),
            comment            => "Remove user at beginning of list";
        "($(group):.*)\K($(user))"

            replace_with        => value(""),
            comment            => "Remove user as only member";

would be safer as it would prevent removing the group itself.

Jon
Reply all
Reply to author
Forward
0 new messages