docker-samba icon indicating copy to clipboard operation
docker-samba copied to clipboard

config.yml - create users and groups separately, allow users to have supplementary groups

Open aTanCS opened this issue 1 year ago • 1 comments

Description

Hello, currently it is not possible for a user to be in several groups, so a share access could be managed by groups only (e.g. group per share). It could be solved by dividing user and groups definitions in confing.yml and allowing users to have multiple groups in group attribute (or use group for a main group and some other attribute for supplementary group list).

aTanCS avatar Apr 25 '24 16:04 aTanCS

@aTanCS

Probably this workaround. Not supposed to break something, it only extends the current image capabilities

Create extra.sh script on your docker host (make sure it is executable: chmod +x ./extra.sh):

#!/usr/bin/with-contenv bash

json_conf() {
  yq --output-format=json e '(.. | select(tag == "!!str")) |= envsubst' "${CONFIG_FILE}" 2>/dev/null
}

if [[ "$(json_conf | jq '.groups')" != "null" ]]; then
  for group in $(json_conf | jq -r '.groups[] | @base64'); do
    _jq() { echo "${group}" | base64 --decode | jq -r "${1}"; }
    name=$(_jq '.name')
    gid=$(_jq '.gid')

    echo "Creating group ${name} ${gid}"
    getent group "${gid}" &>/dev/null || getent group "${gid}" "${name}" &>/dev/null || addgroup -g "${gid}" -S "${name}"
  done
fi

if [[ "$(json_conf | jq '.auth')" != "null" ]]; then
  for auth in $(json_conf | jq -r '.auth[] | @base64'); do
    _jq() { echo "${auth}" | base64 --decode | jq -r "${1}"; }
    [[ "$(_jq '.groups')" == "null" ]] && continue

    echo "Adding user $(_jq '.user') to groups $(_jq '.groups')"
    usermod -aG "$(_jq '.groups')" "$(_jq '.user')"
  done
fi

config.yaml demo (see comments):

---
groups:             # <- Groups declaration
  - name: g1
    gid: 1005
  - name: g2
    gid: 1006

auth:
  - user: foo
    group: foo
    groups: g1,g2   # <- User belongs to groups, no spacing after comma
    uid: 1000
    gid: 1000
    password: bar
  - user: baz
    group: xxx
    groups: g1      # <- User belongs to group
    uid: 1100
    gid: 1200
    password_file: /run/secrets/baz_password

global:
  - "force user = foo"
  - "force group = foo"

share:
  - name: groupped
    path: /samba/g1-g2
    browsable: yes
    readonly: no
    guestok: no
    validusers: '@g1, @g2'  # <- Make use of the created groups, in quotes
    writelist: '@g1, @g2'
    veto: no
# ... Other shares

compose.yaml file sample (see comments):

---
services:
  samba:
    image: crazymax/samba
    container_name: samba
    network_mode: host
    volumes:
      - "./g1-g2-share:/samba/g1-g2"
      # Customizations
      - "./config.yaml:/config.yaml:ro"   # <- Mount your config file
      # Make sure this one is mounted to '/etc/cont-init.d' directory and
      # is processed after '01-config.sh', i.e. '07-' prefix makes it kind of 
      # near future proof
      - "./extra.sh:/etc/cont-init.d/07-extra.sh:ro"
    environment:
      - "CONFIG_FILE=/config.yaml"        # <- Point the config file
      # ... More env vars
    restart: unless-stopped

spaghetti-coder avatar Jun 08 '25 13:06 spaghetti-coder