7

I'd like to script adding a share to a smb.conf file. My current script just appends it to the end of the file, but that's not ideal. I'd rather have something that will add a new share if it doesn't exist, and replace it if it does.

I'm currently scripting this on a CentOS 7 distro, but would ideally like something that would work across distros, though that's not a requirement.

Also, I'm using bash to do this because the script is run before other packages are added to the system. The script uses yum to install the samba packages, and then is supposed to configure it and add shares.

chicks
  • 3,793
  • 10
  • 27
  • 36
Benjamin Peikes
  • 1,094
  • 3
  • 16
  • 26
  • 1
    Check for pre-existing modules for your favourite scripting language. For example, I quickly found [File::Samba](https://metacpan.org/pod/File::Samba) for perl – glenn jackman Dec 05 '14 at 21:07
  • 1
    Can you tell us more about the environment and context of what you are doing? If I had a server and I wanted to programmatically change shares often, then I would create a directory, setup an include for that directory. Then I would just place one file per share in that directory. – Zoredache Dec 05 '14 at 21:25
  • @glennjackman - That would be ideal, but I was hoping to not have to add additional scripting languages and packages. This is part of an rpm and I'd rather not have a lot of pre-requirements. If I'm going to do that, I might as well use saltstack, puppet, chef or another tool like that. I was hoping for something more lightweight. Too bad there isn't a smbconfmerge command. I wonder what saltstack uses? – Benjamin Peikes Dec 09 '14 at 06:06

2 Answers2

9

To fit with modern sysadmin best practices it would be good to add your configs as individual files in /etc/smb/smb.d and then reference them with an include. Sadly samba does not support wildcard includes so you have to do add something like:

include = /etc/smb/includes.conf

in your smb.conf and then generate the includes.conf with something like:

ls /etc/smb/smb.d/* | sed -e 's/^/include = /' > /etc/smb/includes.conf

For a bit more context:

chicks@silver 23:57:23 smb !531 $ ls smb.d
a.conf  c.conf  e.conf
chicks@silver 23:57:29 smb !532 $ ls /etc/smb/smb.d/* | sed -e 's/^/include = /' > /etc/smb/includes.conf
chicks@silver 23:57:40 smb !533 $ cat includes.conf 
include = /etc/smb/smb.d/a.conf
include = /etc/smb/smb.d/c.conf
include = /etc/smb/smb.d/e.conf

So now you can stick any additional samba configs into /etc/smb/smb.d, regenerate includes.conf and restart samba and life is good.

chicks
  • 3,793
  • 10
  • 27
  • 36
  • Is that independent of the distro? Also, how does that work if you want to update parameters as well as add/remove shares? – Benjamin Peikes Dec 08 '14 at 14:48
  • 1
    Yep, that should work well regardless of distro (unless the distro comes with something like this already, but I haven't seen one yet). It'd be the same procedure no matter what you're changing: make x.conf changes/additions/removal, rebuild includes.conf, restart the daemon. – Chris S Dec 08 '14 at 14:57
  • This doesn't work with global settings. It also doesn't fix the issue that a particular share name could be added to one of the a.conf, b.conf, or c.conf files already. – Benjamin Peikes Dec 09 '14 at 06:02
  • There's nothing to stop you from grepping through all of the configs and making sure they are up to some standard. You could use a similar mechanism for global settings too. One include for global settings would point to `*.conf` and another for shares would point to `*.share`. – chicks Dec 09 '14 at 18:22
  • https://docs.ansible.com/ansible/latest/modules/lineinfile_module.html would be another way to handle this. – chicks Jul 16 '20 at 14:54
0

This is an old topic but still useful. This are my scripts to create and delete users in a simple samba installation for storing backups.

Tested on CentOS

Prepare directory and permissions

Run this commands on a terminal

sudo mkdir /backups
sudo mkdir /etc/samba/smb.conf.d
sudo groupadd sambashare 
sudo chgrp sambashare /backups
sudo useradd -M -d /home/sadmin -s /usr/sbin/nologin -G sambashare sadmin
sudo smbpasswd -a sadmin
sudo smbpasswd -e sadmin

smb.conf

[global]
    workgroup = TUAITI
    security = user

    passdb backend = tdbsam

    printing = cups
    printcap name = cups
    load printers = yes
    cups options = raw

include = /etc/samba/includes.conf

smbaddshare.sh

#!/bin/bash
USER=$1
if [ -z "$1" ]
then
    echo "No username given"
    exit 1
fi

useradd -M -d /backups/$USER -s /usr/sbin/nologin -G sambashare $USER
mkdir /backups/$USER
chown $USER:sambashare /backups/$USER
chmod 2770 /backups/$USER
smbpasswd -a $USER
smbpasswd -e $USER

cat  /etc/samba/smb.conf.d/$USER.conf
[$USER]
    path = /backups/$USER
    browseable = no
    read only = no
    force create mode = 0660
    force directory mode = 2770
    valid users = $USER @sadmin
EOF

ls /etc/samba/smb.conf.d/* | sed -e 's/^/include = /' > /etc/samba/includes.conf

smbcontrol all reload-config

smbremoveshare.sh

#!/bin/bash
USER=$1
if [ -z "$1" ]
then
    echo "No username given"
    exit 1
fi

read -r -p "Are you sure you want to delete the user ? [y/N] " response
response=${response,,}    # tolower
if [[ "$response" =~ ^(yes|y)$ ]]
then
    smbpasswd -x $USER
    userdel $USER
    mv /backups/$USER /backups/$USER.`date +"%Y%m%d%H%M%S"`.deleted
    rm /etc/samba/smb.conf.d/$USER.conf

    ls /etc/samba/smb.conf.d/* | sed -e 's/^/include = /' > /etc/samba/includes.conf

    smbcontrol all reload-config
else
    echo "Nothing done"
fi