Non interactive samba user creation via ansible
Asked Answered
B

6

9

Although the following command works when typing in in shell

echo -ne "myser\nmypass\n" | smbpasswd -a -s myuser

The following task fails in ansible

  - name: add dms samba user
    command: echo -ne "myuser\nmypass\n" | smbpasswd -a -s myuser
    notify: restart samba

It does not produce any errors, but the user is not created.

Working with ansible 2.3.0.0 on Ubuntu 16.0.4.

Blackshear answered 26/6, 2017 at 14:50 Comment(1)
Possible duplicate of How to use wildcard with variableAll
C
12

As stated, pipes won't work with the command module. I've used something like this in the past to create Samba users:

- name: Configure Samba users.
  shell: >
    (pdbedit --user={{ item.username }} 2>&1 > /dev/null)
    || (echo '{{ item.password }}'; echo '{{ item.password }}')
    | smbpasswd -s -a {{ item.username }}
  register: smbpasswd
  changed_when: "'Added user' in smbpasswd.stdout"
  with_items: "{{ samba_users }}"
  loop_control:
    label: "{{ item.username }}"

The task will only run if the user does not exist yet. So changing passwords won't work with this example.

Curtis answered 26/9, 2017 at 13:47 Comment(0)
T
7

I improved the code from siwyd and Tormod Macleod slightly. Thanks to both of you!

- name: shell - create samba users
  ansible.builtin.shell: >
    set -e -o pipefail
    && (pdbedit --user={{ item.username }} 2>&1 > /dev/null)
    || (echo '{{ item.password }}'; echo '{{ item.password }}')
    | smbpasswd -s -a {{ item.username }}
  args:
    executable: /bin/bash
  register: samba_create_users
  changed_when: "'Added user' in samba_create_users.stdout"
  loop: "{{ samba_users }}"
  no_log: true

- name: shell - set samba passwords correctly
  ansible.builtin.shell: >
    set -e -o pipefail
    && (smbclient -U {{ item.username }}%{{ item.password }} -L 127.0.0.1 2>&1 > /dev/null)
    || (echo '{{ item.password }}'; echo '{{ item.password }}')
    | smbpasswd {{ item.username }}
  args:
    executable: /bin/bash
  register: samba_verify_users
  changed_when: "'New SMB password' in samba_verify_users.stdout"
  loop: "{{ samba_users }}"
  no_log: true

Changes:

Titanesque answered 9/2, 2022 at 13:54 Comment(1)
This should probably be the accepted answer. Note that ansible-lint also prefers the use of FQCNs (ansible.builtin.shell).Jonathanjonathon
C
3

Please try this approach with your Ansible Playbook:

- name: set Samba passwords for each user
  shell: "printf '{{ item.passwd }}\n{{ item.passwd }}\n' | smbpasswd -a {{ item.name }}"
  with_items:
  - "{{ users }}"
  tags: smbpasswd

Please note that you will need to map your variables file that includes users: with the format of:

users:
- name: userName
  passwd: myClearTextPassword

Please note that to support smbpasswd you will be passing this password as clear text. Additionally, noting this is only a single task that would need to be included in your playbook.

Comedown answered 3/11, 2017 at 17:49 Comment(0)
T
1

The answer by siwyd above is excellent. I was struggling to figure out how to solve this problem in an idempotent way until I saw this. For my use-case, I'd like to keep the passwords in sync so I've added another play to do this. Might be useful for someone

- name: shell - create samba users
  shell: >
    (pdbedit --user={{ item.username }} 2>&1 > /dev/null)
    || (echo '{{ item.password }}'; echo '{{ item.password }}')
    | smbpasswd -s -a {{ item.username }}
  register: create_samba_users
  changed_when: "'Added user' in create_samba_users.stdout"
  become: true
  with_items: "{{ samba_users }}"
  loop_control:
    label: "{{ item.username }}"

- name: shell - set samba passwords correctly
  shell: >
    (smbclient -U {{ item.username }}%{{ item.password }} -L 127.0.0.1 2>&1 > /dev/null)
    || (echo '{{ item.password }}'; echo '{{ item.password }}')
    | smbpasswd {{ item.username }}
  register: verify_samba_users
  changed_when: "'New SMB password' in verify_samba_users.stdout"
  become: true
  with_items: "{{ samba_users }}"
  loop_control:
    label: "{{ item.username }}"
Thor answered 3/1, 2022 at 12:59 Comment(0)
T
0

the command module does not support pipelining. use the shell module for stuff like this.

see:

Thin answered 26/6, 2017 at 16:17 Comment(0)
C
-1

Another variant using dictionary lists:

ad_users: [
             { username: john.doe, password: P4ssw0rd*, givenname: John, surname: Doe, mail: john.doe@domain, ou: "OU=Department,OU=Division" },
             { username: jane.doe, password: P455w0rd*, givenname: Jane, surname: Doe, mail: jane.doe@domain, ou: "OU=Department,OU=Division" },
             ]


- name: Add user to AD
  command: samba-tool user create {{ item.username }} {{ item.password }} --given-name='{{ item.givenname }}' --surname='{{ item.surname }}' --mail-address={{ item.mail }} --userou='{{ item.ou }}'
  loop: "{{ ad_users }}"

Just remember to vault sensitive data.

Credential answered 30/7, 2021 at 6:44 Comment(1)
samba-tool will work ONLY for computers with ActiveDirectory (Windows network). This does not cover typical cases when Samba is configured as FileServer.Kilter

© 2022 - 2024 — McMap. All rights reserved.