Repository: ansible/ansible-modules-core

Issue:
User module - existing user groups removed, even with append set as yes (OS X)
##### Issue Type:

Bug Report
##### Ansible Version:

```
ansible 1.9.3
  configured module search path = None
```
##### Ansible Configuration:

```
cat: /etc/ansible/ansible.cfg: No such file or directory
cat: ~/.ansible.cfg: No such file or directory
```
##### Environment:

OS X 10.11 Beta (15A243d)
##### Summary:

I attempted to add a new group **groupexample** to the user that was running the playbook, and added `append: yes` per the [docs](http://docs.ansible.com/ansible/user_module.html), as I wanted to ensure that the existing groups were left intact.
The task completed successfully, and the new group **groupexample** was added the the user successfully, but the user was now missing other (very important!) system groups, such as **admin**.
##### Steps To Reproduce:

```
$ cat playbook.yml

---
- hosts: all
  connection: local
  tasks:
    - name: ensure groupexample group exists
      become: yes
      group:
        name: groupexample
        state: present

    - name: add groupexample group to current user
      become: yes
      user:
        name: "{{ ansible_user_id }}"
        groups: groupexample
        append: yes
```

```
$ ansible-playbook --ask-become-pass playbook.yml -i inventory/hosts
SUDO password:

PLAY [all] ********************************************************************

GATHERING FACTS ***************************************************************
ok: [localhost]

TASK: [ensure groupexample group exists] **************************************
changed: [localhost]

TASK: [add groupexample group to current user] ********************************
changed: [localhost]

PLAY RECAP ********************************************************************
localhost                  : ok=3    changed=2    unreachable=0    failed=0
```
##### Expected Results:

```
$ groups
staff admin wheel everyone localaccounts groupexample
```

(OS X underscore and com groups removed for brevity)
##### Actual Results:

```
$ groups
groupexample everyone localaccounts
```

(OS X underscore and com groups removed for brevity)
##### Other notes

For any other poor souls that may also be running a single user machine who then loose the groups that allow them to administer the OS:
- Boot into single user mode (power off, hold command+s, power on)
- Run `visudo`
- Add your username to list of sudoers, for example

```
root ALL=(ALL) ALL
%admin  ALL=(ALL) ALL
yourusernamehere ALL=(ALL) ALL
```
- Save, quit, `reboot`
- You can now boot into OS X normally, and re add your lost groups with:

```
sudo dseditgroup -o edit -a yourusernamehere -t user admin
sudo dseditgroup -o edit -a yourusernamehere -t user wheel
sudo dseditgroup -o edit -a yourusernamehere -t user staff
```



Discussion:
[module: system/user.py]

Hi @d3v1an7 -- thanks for this (very excellent!) bug report and suggestions.

@sfromm -- thanks in advance for taking a look at this bug report and for your ongoing work in maintaining this module.

I just ran across this issue as well. Are there any updates to this issue or is there a known workaround? Would running `dseditgroup` with the shell module be preferable until a fix is implemented? Thanks!


Resolving patch:
diff --git a/system/user.py b/system/user.py
--- a/system/user.py
+++ b/system/user.py
@@ -1546,12 +1546,13 @@ def _modify_group(self):
         else:
             target = set([])
 
-        for remove in current - target:
-            (_rc, _err, _out) = self.__modify_group(remove, 'delete')
-            rc += rc
-            out += _out
-            err += _err
-            changed = True
+        if self.append is False:
+            for remove in current - target:
+                (_rc, _err, _out) = self.__modify_group(remove, 'delete')
+                rc += rc
+                out += _out
+                err += _err
+                changed = True
 
         for add in target - current:
             (_rc, _err, _out) = self.__modify_group(add, 'add')


Test patch: