#!/bin/bash # ============================================================================= # Universal Samba Share Manager - FSA (Fucking Samba Ass) # ============================================================================= # Works on: Debian, Ubuntu, Arch Linux, RHEL/CentOS, Fedora # Auto-detects distribution and installs Samba if needed # ============================================================================= # Zkontrolujte, zda je skript spuštěn jako root if [ "$EUID" -ne 0 ]; then echo "Tento skript je nutné spustit s právy roota (sudo)." exit 1 fi # --- Detekce distribuce a správce balíčků --- detect_distro() { if [ -f /etc/os-release ]; then . /etc/os-release DISTRO_ID="$ID" DISTRO_NAME="$NAME" elif [ -f /etc/arch-release ]; then DISTRO_ID="arch" DISTRO_NAME="Arch Linux" elif [ -f /etc/debian_version ]; then DISTRO_ID="debian" DISTRO_NAME="Debian" else DISTRO_ID="unknown" DISTRO_NAME="Unknown Linux" fi echo "Detected distribution: $DISTRO_NAME" } # --- Instalace Samby pokud není nainstalovaná --- install_samba() { echo "Kontroluji instalaci Samby..." # Zkontroluj jestli už není Samba nainstalovaná if command -v smbd &> /dev/null; then echo "✅ Samba je již nainstalována." return 0 fi echo "⚠️ Samba není nainstalována. Instaluji..." case "$DISTRO_ID" in arch|manjaro) pacman -Sy --noconfirm samba ;; ubuntu|debian|linuxmint|pop) apt-get update apt-get install -y samba samba-common-bin ;; fedora) dnf install -y samba samba-common ;; rhel|centos|rocky|almalinux) yum install -y samba samba-common ;; opensuse*|sles) zypper install -y samba ;; *) echo "❌ CHYBA: Nepodařilo se detekovat distribuci pro automatickou instalaci." echo "Prosím nainstalujte Sambu manuálně a spusťte skript znovu." exit 1 ;; esac if [ $? -eq 0 ]; then echo "✅ Samba byla úspěšně nainstalována." else echo "❌ Instalace Samby selhala!" exit 1 fi } # --- Auto-detekce uživatele a síťových rozhraní --- DETECTED_USER="${SUDO_USER:-$(whoami)}" DETECTED_INTERFACES=$(ip -o link show | awk -F': ' '{print $2}' | grep -v '^lo$' | tr '\n' ' ') # --- Nastavení sdílení --- declare -A SHARES=( ["${DETECTED_USER}-home"]="/home/${DETECTED_USER}|Domovska slozka uzivatele ${DETECTED_USER}|home" ) CONFIG_FILE="/etc/samba/smb.conf" BACKUP_FILE="/etc/samba/smb.conf.bak.$(date +%F_%T)" # Spusť detekci distribuce a instalaci Samby detect_distro install_samba # Funkce pro kontrolu existence smb.conf check_config_exists() { if [ ! -f "$CONFIG_FILE" ]; then echo "Chyba: Konfigurační soubor $CONFIG_FILE neexistuje!" echo "Pokud je Samba nově nainstalovaná, vytvořte ho z šablony příkazem:" echo "sudo cp /etc/samba/smb.conf.default /etc/samba/smb.conf" exit 1 fi } # VYLEPŠENÁ FUNKCE: Najde všechny diskové oddíly a správně očistí jejich názvy discover_mounts() { local verbose="$1" if [ "$verbose" = "verbose" ]; then echo "=== HLEDÁNÍ DISKOVÝCH ODDÍLŮ ===" fi # Vyčisti předchozí disky z SHARES for key in "${!SHARES[@]}"; do if [[ $key == disk-* ]]; then unset SHARES[$key] fi done local disk_count=0 while read -r name label uuid mountpoint; do # Odstranění stromových znaků (└─, ├─) z názvu zařízení name=$(echo "$name" | sed 's/^[├└]─//g' | sed 's/ //g') # Přeskoč prázdné řádky nebo loopback zařízení if [ -z "$name" ] || [[ "$name" == loop* ]]; then continue fi local identifier="${label:-$name}" local clean_identifier clean_identifier=$(echo "$identifier" | sed 's/[^a-zA-Z0-9_-]//g') # Záložní varianta pro prázdné popisky if [ -z "$clean_identifier" ]; then clean_identifier="$name" fi local share_name="disk-$clean_identifier" local share_path="" local status_info="" if [ -n "$mountpoint" ]; then share_path="$mountpoint" local disk_info=$(df -h "$mountpoint" 2>/dev/null | tail -1 | awk '{print "("$2" celkem, "$4" volné)"}') status_info="✅ Připojeno na $mountpoint $disk_info" else share_path="/mnt/$clean_identifier" status_info="❌ Nepřipojeno (navrhovaná cesta: $share_path)" fi if [ -n "$clean_identifier" ]; then SHARES["$share_name"]="$share_path|Oddíl $identifier ($name)|disk|$name|$uuid" disk_count=$((disk_count + 1)) if [ "$verbose" = "verbose" ]; then echo " [$disk_count] $name (Label: $identifier) - $status_info" fi fi done < <(lsblk -no NAME,LABEL,UUID,MOUNTPOINT -e7,1 | grep -v '^$') if [ "$verbose" = "verbose" ]; then if [ $disk_count -eq 0 ]; then echo " Žádné diskové oddíly nebyly nalezeny." else echo "" echo "Celkem nalezeno: $disk_count oddílů" fi fi } # Funkce pro vytvoření dfree skriptu pro konkrétní disk create_dfree_script() { local mount_point="$1" local script_name="samba-dfree-$(basename "$mount_point").sh" local script_path="/usr/local/bin/$script_name" cat > "$script_path" << EOT #!/bin/bash # Auto-generated dfree script for $mount_point MOUNT_PATH="$mount_point" if [ -d "\$MOUNT_PATH" ]; then df -k --output=size,avail "\$MOUNT_PATH" | tail -n 1 else echo "0 0" fi EOT chmod +x "$script_path" echo "$script_path" } # Funkce pro vytvoření kompletní smb.conf s [global] sekcí create_complete_smb_config() { echo "Vytvářím kompletní SMB konfiguraci..." local HOSTNAME=$(hostname | tr '[:lower:]' '[:upper:]') cat > "$CONFIG_FILE" < /dev/null 2>&1; then groupadd sambashare 2>/dev/null || true fi } # CRITICAL SAFETY: Check if path is safe to modify recursively is_safe_path_for_permissions() { local path="$1" # Blacklist of DANGEROUS paths that should NEVER be modified local dangerous_paths=( "/" "/bin" "/boot" "/dev" "/etc" "/lib" "/lib64" "/opt" "/proc" "/root" "/run" "/sbin" "/sys" "/tmp" "/usr" "/var" ) # Check if path matches any dangerous path for dangerous in "${dangerous_paths[@]}"; do if [ "$path" = "$dangerous" ] || [[ "$path" == "$dangerous"/* ]]; then echo "⚠️ NEBEZPEČNÉ: Odmítám měnit oprávnění pro $path (systémový adresář)" return 1 fi done # Only allow /mnt/* and /home/*/specific-dirs (but not /home itself) if [[ "$path" == /mnt/* ]]; then return 0 elif [[ "$path" == /home/*/* ]]; then # Allow /home/user/something but not /home or /home/user return 0 else echo "⚠️ VAROVÁNÍ: $path není v bezpečné cestě (/mnt/* nebo /home/user/dir)" return 1 fi } # OPRAVENÁ FUNKCE: Vytvoří sdílení se správným formátováním a `force user` create_share() { local share_name="$1" if [ -z "$share_name" ]; then echo "Chybí název sdílení."; return 1; fi if [ -z "${SHARES[$share_name]}" ]; then echo "Neznámé sdílení: $share_name"; return 1; fi check_config_exists IFS='|' read -r share_path comment share_type device_name uuid <<< "${SHARES[$share_name]}" if grep -Fq "[$share_name]" "$CONFIG_FILE"; then echo "Chyba: Sdílení s názvem [$share_name] již existuje."; return 1; fi if [ ! -d "$share_path" ]; then echo "Varování: Cesta '$share_path' neexistuje." read -p "Chcete ji vytvořit? (Y/n): " -n 1 -r; echo if [[ ! $REPLY =~ ^[Nn]$ ]]; then if ! mkdir -p "$share_path"; then echo "Chyba: Nepodařilo se vytvořit adresář."; return 1; fi echo "Adresář vytvořen." else echo "Operace zrušena."; return 1 fi fi echo "Přidávám nové sdílení '[$share_name]' do $CONFIG_FILE..." case "$share_type" in "home") cat <> "$CONFIG_FILE" [$share_name] path = $share_path writable = yes guest ok = yes hosts allow = 127.0.0.1 192.168.0.0/16 10.0.0.0/8 172.16.0.0/12 100.64.0.0/10 comment = $comment EOT ;; "disk") local dfree_script=$(create_dfree_script "$share_path") # Zajisti existenci skupiny sambashare ensure_sambashare_group # Přidej detekovaného uživatele do sambashare if ! groups "$DETECTED_USER" 2>/dev/null | grep -q "sambashare"; then usermod -a -G sambashare "$DETECTED_USER" 2>/dev/null || true fi # Nastav filesystem permissions - ONLY FOR SAFE PATHS if [ -d "$share_path" ] && is_safe_path_for_permissions "$share_path"; then echo " - Nastavuji oprávnění pro $share_path" chown -R :sambashare "$share_path" 2>/dev/null || true chmod -R g+rw "$share_path" 2>/dev/null || true chmod g+s "$share_path" 2>/dev/null || true elif [ -d "$share_path" ]; then echo " - ⚠️ Přeskakuji nastavení oprávnění (systémový adresář)" echo " - Pro přístup nastavte oprávnění manuálně" fi cat <> "$CONFIG_FILE" [$share_name] path = $share_path writable = yes guest ok = no valid users = $DETECTED_USER force group = sambashare create mask = 0664 directory mask = 0775 dfree command = $dfree_script hosts allow = 127.0.0.1 192.168.0.0/16 10.0.0.0/8 172.16.0.0/12 100.64.0.0/10 comment = $comment EOT echo "Vytvořen dfree skript: $dfree_script" ;; *) cat <> "$CONFIG_FILE" [$share_name] path = $share_path writable = yes guest ok = yes hosts allow = 127.0.0.1 192.168.0.0/16 10.0.0.0/8 172.16.0.0/12 100.64.0.0/10 comment = $comment EOT ;; esac if [ $? -eq 0 ]; then echo "Nové sdílení '$share_name' bylo přidáno."; else echo "Chyba při přidávání sdílení."; return 1; fi } # Funkce pro smazání sdílení delete_share() { local share_name="$1" if [ -z "$share_name" ]; then echo "Použití: sudo $0 delete "; exit 1; fi check_config_exists if ! grep -Fq "[$share_name]" "$CONFIG_FILE"; then echo "Chyba: Sdílení [$share_name] nebylo nalezeno."; exit 1; fi echo "Vytvářím zálohu..."; cp "$CONFIG_FILE" "$BACKUP_FILE"; echo "Mažu sdílení '[$share_name]'..." awk -v section="[$share_name]" 'BEGIN{p=1} /^\[/{p=($0!=section)} p' "$CONFIG_FILE" > "${CONFIG_FILE}.tmp" && mv "${CONFIG_FILE}.tmp" "$CONFIG_FILE" local dfree_script="/usr/local/bin/samba-dfree-${share_name#disk-}.sh" if [ -f "$dfree_script" ]; then echo "Mažu dfree skript: $dfree_script"; rm -f "$dfree_script"; fi echo "Sdílení '$share_name' bylo smazáno." } # Funkce pro zobrazení existujících sdílení list_shares() { check_config_exists echo "Existující sdílení v $CONFIG_FILE:"; echo "==================================" grep -E "^\[.*\]" "$CONFIG_FILE" | grep -v "\[global\]" } # Funkce pro vytvoření všech sdílení včetně automatického mountování disků create_all() { echo "=== KOMPLETNÍ NASTAVENÍ VŠECH SDÍLENÍ ===" echo "" # 1. Vytvoř statická sdílení echo "Krok 1/4: Vytvářím statická sdílení..." create_share "${DETECTED_USER}-home" echo "" echo "Krok 2/4: Hledám diskové oddíly..." discover_mounts verbose # 2. Zpracuj všechny nalezené disky local unmounted_disks=() local mounted_disks=() for share_name in "${!SHARES[@]}"; do IFS='|' read -r path comment share_type device_name uuid <<< "${SHARES[$share_name]}" if [ "$share_type" = "disk" ]; then if mountpoint -q "$path" 2>/dev/null; then mounted_disks+=("$share_name|$path|$device_name|$uuid") else unmounted_disks+=("$share_name|$path|$device_name|$uuid") fi fi done echo "" echo "Krok 3/4: Připojuji nepřipojené disky..." if [ ${#unmounted_disks[@]} -gt 0 ]; then for disk_info in "${unmounted_disks[@]}"; do IFS='|' read -r share_name path device_name uuid <<< "$disk_info" if [ -z "$uuid" ]; then echo " ⚠️ Přeskakuji $device_name - nemá UUID" continue fi echo " Připojuji /dev/$device_name na $path..." # Vytvoř mount point if [ ! -d "$path" ]; then mkdir -p "$path" fi # Připoj disk if mount "/dev/$device_name" "$path" 2>/dev/null; then echo " ✅ Úspěšně připojeno" # Přidej do fstab if ! grep -q "$uuid" /etc/fstab 2>/dev/null; then local fstype=$(lsblk -no FSTYPE "/dev/$device_name" 2>/dev/null) if [ -n "$fstype" ]; then echo " Přidávám do /etc/fstab..." echo "" >> /etc/fstab echo "# Auto-added by FSA on $(date)" >> /etc/fstab echo "UUID=$uuid $path $fstype defaults,nofail 0 2" >> /etc/fstab echo " ✅ Přidáno do /etc/fstab" fi fi mounted_disks+=("$share_name|$path|$device_name|$uuid") else echo " ❌ Nepodařilo se připojit" fi done else echo " Žádné nepřipojené disky k připojení." fi echo "" echo "Krok 4/4: Vytvářím Samba sdílení pro připojené disky..." if [ ${#mounted_disks[@]} -gt 0 ]; then for disk_info in "${mounted_disks[@]}"; do IFS='|' read -r share_name path device_name uuid <<< "$disk_info" echo " Vytvářím sdílení: $share_name" create_share "$share_name" done else echo " Žádné připojené disky k nasdílení." fi echo "" echo "✅ HOTOVO! Všechna sdílení byla vytvořena." } # Funkce pro automatické vytvoření sdílení pro všechny disky auto_discover_and_create() { echo "=== AUTOMATICKÉ VYTVÁŘENÍ SDÍLENÍ PRO PŘIPOJENÉ DISKY ===" discover_mounts verbose echo "" local created_count=0 for share_name in "${!SHARES[@]}"; do IFS='|' read -r path comment share_type device_name uuid <<< "${SHARES[$share_name]}" if [ "$share_type" = "disk" ]; then if mountpoint -q "$path" 2>/dev/null; then echo "--- Vytvářím sdílení pro připojený disk: $share_name ---" create_share "$share_name" created_count=$((created_count + 1)) fi fi done echo "" if [ $created_count -eq 0 ]; then echo "Žádné připojené disky k nasdílení." else echo "✅ Vytvořeno $created_count sdílení pro připojené disky." fi } # Funkce pro přidání [global] sekce do existující konfigurace add_global_section() { echo "=== PŘIDÁVÁNÍ [GLOBAL] SEKCE ===" if grep -q "^\[global\]" "$CONFIG_FILE"; then echo "Sekce [global] již existuje."; return; fi echo "Vytvářím zálohu..."; cp "$CONFIG_FILE" "$BACKUP_FILE"; echo "Přidávám [global] na začátek..." local HOSTNAME=$(hostname | tr '[:lower:]' '[:upper:]') local GLOBAL_CONFIG=$(cat < "${CONFIG_FILE}.tmp" && mv "${CONFIG_FILE}.tmp" "$CONFIG_FILE" echo "Sekce [global] byla přidána." } # Funkce pro inicializaci kompletní konfigurace init_config() { echo "=== INICIALIZACE NOVÉ SMB KONFIGURACE ===" if [ -f "$CONFIG_FILE" ]; then echo "Zálohuji stávající konfiguraci..."; mv "$CONFIG_FILE" "${CONFIG_FILE}.backup-$(date +%F_%T)"; fi create_complete_smb_config create_share "${DETECTED_USER}-home" read -p "Přidat automaticky všechny nalezené PŘIPOJENÉ disky? (Y/n): " -n 1 -r; echo if [[ ! $REPLY =~ ^[Nn]$ ]]; then auto_discover_and_create fi echo "Inicializace dokončena!" } # Funkce pro testování a restart test_and_restart() { echo ""; echo "Kontroluji syntaxi..."; if ! testparm -s > /dev/null 2>&1; then echo "CHYBA: Konfigurace Samby je neplatná! Změny nebyly aplikovány."; testparm -s; exit 1 fi echo "Restartuji služby SMB a NMB..." # Detekuj správné názvy služeb pro různé distribuce local SMB_SERVICE="" local NMB_SERVICE="" if systemctl list-unit-files | grep -q "^smbd.service"; then SMB_SERVICE="smbd.service" NMB_SERVICE="nmbd.service" elif systemctl list-unit-files | grep -q "^smb.service"; then SMB_SERVICE="smb.service" NMB_SERVICE="nmb.service" elif systemctl list-unit-files | grep -q "^samba.service"; then SMB_SERVICE="samba.service" NMB_SERVICE="" fi if [ -z "$SMB_SERVICE" ]; then echo "CHYBA: Nepodařilo se najít Samba službu!" exit 1 fi # Aktivuj a restartuj služby systemctl enable "$SMB_SERVICE" 2>/dev/null if [ -n "$NMB_SERVICE" ]; then systemctl enable "$NMB_SERVICE" 2>/dev/null if systemctl restart "$SMB_SERVICE" "$NMB_SERVICE"; then echo "Služby SMB úspěšně restartovány." else echo "CHYBA: Restart služeb selhal. Zkontrolujte logy pomocí 'journalctl -u $SMB_SERVICE'." exit 1 fi else if systemctl restart "$SMB_SERVICE"; then echo "Služby SMB úspěšně restartovány." else echo "CHYBA: Restart služeb selhal. Zkontrolujte logy pomocí 'journalctl -u $SMB_SERVICE'." exit 1 fi fi echo "Hotovo! ✅" } # NOVÁ FUNKCE: Přidá záznam do /etc/fstab add_to_fstab() { local device_name="$1"; local mount_path="$2" local device_info; device_info=$(lsblk -no UUID,FSTYPE "/dev/$device_name"); local uuid; uuid=$(echo "$device_info" | awk '{print $1}'); local fstype; fstype=$(echo "$device_info" | awk '{print $2}') if [ -z "$uuid" ] || [ -z "$fstype" ]; then echo "Chyba: Nepodařilo se zjistit UUID."; return 1; fi echo " - UUID: $uuid"; echo " - Typ: $fstype" if grep -q "$uuid" /etc/fstab; then echo "Varování: Záznam pro UUID již existuje."; return 0; fi local fstab_line="UUID=$uuid $mount_path $fstype defaults,nofail 0 2" echo "Přidávám do /etc/fstab:"; echo " $fstab_line" echo "" >> /etc/fstab; echo "# Přidáno skriptem spravuj_sdileni.sh dne $(date)" >> /etc/fstab; echo "$fstab_line" >> /etc/fstab if [ $? -eq 0 ]; then echo "✅ Záznam úspěšně přidán."; else echo "Chyba: Zápis do /etc/fstab selhal."; return 1; fi } # NOVÁ FUNKCE: Interaktivně připojí a nasdílí disk interactive_mount_and_create() { local mode="$1" echo "=== INTERAKTIVNÍ PŘIPOJENÍ A SDÍLENÍ DISKU ===" local unmounted_partitions=() while read -r name label uuid mountpoint; do if [ -z "$mountpoint" ]; then name=$(echo "$name" | sed 's/^[├└]─//g' | sed 's/ //g') local identifier="${label:-$name}" unmounted_partitions+=("$name|$identifier") fi done < <(lsblk -no NAME,LABEL,UUID,MOUNTPOINT -e7,1) if [ ${#unmounted_partitions[@]} -eq 0 ]; then echo "Nenalezeny žádné nepřipojené diskové oddíly."; exit 0; fi echo "Který oddíl chcete připojit a sdílet?" local i=1 for info in "${unmounted_partitions[@]}"; do IFS='|' read -r name identifier <<< "$info"; echo " $i) $name (Popisek: $identifier)"; i=$((i+1)); done echo " 0) Zrušit" local choice read -p "Zadejte číslo: " choice if ! [[ "$choice" =~ ^[0-9]+$ ]] || [ "$choice" -lt 0 ] || [ "$choice" -gt ${#unmounted_partitions[@]} ]; then echo "Chyba: Neplatná volba."; exit 1; fi if [ "$choice" -eq 0 ]; then echo "Operace zrušena."; exit 0; fi IFS='|' read -r selected_device selected_identifier <<< "${unmounted_partitions[$((choice-1))]}" local clean_identifier; clean_identifier=$(echo "$selected_identifier" | sed 's/[^a-zA-Z0-9_-]//g') if [ -z "$clean_identifier" ]; then clean_identifier="$selected_device" fi local default_mount_path="/mnt/$clean_identifier" read -p "Zadejte cestu pro připojení [navrženo: $default_mount_path]: " mount_path mount_path="${mount_path:-$default_mount_path}" if [ ! -d "$mount_path" ]; then echo "Vytvářím adresář $mount_path..."; if ! mkdir -p "$mount_path"; then echo "Chyba: Nelze vytvořit adresář."; exit 1; fi; fi echo "Připojuji /dev/$selected_device na $mount_path..." if ! mount "/dev/$selected_device" "$mount_path"; then echo "CHYBA: Nepodařilo se připojit disk! (mount /dev/$selected_device)"; exit 1; fi echo "✅ Disk úspěšně připojen." if [ "$mode" == "always" ]; then echo ""; add_to_fstab "$selected_device" "$mount_path" else echo "INFO: Disk je připojen pouze dočasně." fi local share_name="disk-$clean_identifier" echo ""; echo "Nyní vytvářím Samba sdílení s názvem '$share_name'..." # Získej UUID pro správnou identifikaci local device_uuid=$(lsblk -no UUID "/dev/$selected_device" 2>/dev/null) SHARES["$share_name"]="$mount_path|Oddíl $selected_identifier|disk|$selected_device|$device_uuid" create_share "$share_name" } # ============================================================================= # USER MANAGEMENT FUNCTIONS # ============================================================================= # Funkce pro zobrazení všech Samba uživatelů list_samba_users() { echo "=== SEZNAM SAMBA UŽIVATELŮ ===" if ! command -v pdbedit &> /dev/null; then echo "Příkaz 'pdbedit' není k dispozici. Nemohu zobrazit uživatele." return 1 fi local users=$(pdbedit -L 2>/dev/null) if [ -z "$users" ]; then echo "Žádní Samba uživatelé nejsou nastaveni." else echo "$users" fi } # Funkce pro vytvoření nového Samba uživatele create_samba_user() { local username="$1" if [ -z "$username" ]; then echo -n "Zadejte uživatelské jméno: " read username fi if [ -z "$username" ]; then echo "Chyba: Uživatelské jméno je povinné." return 1 fi # Zkontroluj jestli systémový uživatel existuje if ! id "$username" &>/dev/null; then echo "Systémový uživatel '$username' neexistuje." read -p "Chcete vytvořit systémového uživatele? (Y/n): " -n 1 -r; echo if [[ ! $REPLY =~ ^[Nn]$ ]]; then useradd -M -s /sbin/nologin "$username" if [ $? -ne 0 ]; then echo "Chyba: Nepodařilo se vytvořit systémového uživatele." return 1 fi echo "✅ Systémový uživatel '$username' byl vytvořen." else echo "Operace zrušena." return 1 fi fi # Přidej uživatele do Samby echo "Nastavte Samba heslo pro uživatele '$username':" if smbpasswd -a "$username"; then echo "✅ Samba uživatel '$username' byl úspěšně vytvořen." # Nabídni možnost přiřadit přístup ke sdílením echo "" read -p "Chcete nastavit přístup ke sdílením? (Y/n): " -n 1 -r; echo if [[ ! $REPLY =~ ^[Nn]$ ]]; then configure_user_shares "$username" fi else echo "Chyba: Vytvoření Samba uživatele selhalo." return 1 fi } # Funkce pro smazání Samba uživatele delete_samba_user() { local username="$1" if [ -z "$username" ]; then echo -n "Zadejte uživatelské jméno k odstranění: " read username fi if [ -z "$username" ]; then echo "Chyba: Uživatelské jméno je povinné." return 1 fi # Zkontroluj jestli Samba uživatel existuje if ! pdbedit -L 2>/dev/null | grep -q "^$username:"; then echo "Chyba: Samba uživatel '$username' neexistuje." return 1 fi echo "VAROVÁNÍ: Chystáte se odstranit Samba uživatele '$username'" read -p "Jste si jistí? (y/N): " -n 1 -r; echo if [[ $REPLY =~ ^[Yy]$ ]]; then if smbpasswd -x "$username"; then echo "✅ Samba uživatel '$username' byl odstraněn." read -p "Odstranit také systémového uživatele? (y/N): " -n 1 -r; echo if [[ $REPLY =~ ^[Yy]$ ]]; then userdel "$username" echo "✅ Systémový uživatel '$username' byl odstraněn." fi else echo "Chyba: Odstranění Samba uživatele selhalo." return 1 fi else echo "Operace zrušena." fi } # Funkce pro nastavení přístupu uživatele ke sdílením configure_user_shares() { local username="$1" if [ -z "$username" ]; then echo -n "Zadejte uživatelské jméno: " read username fi if [ -z "$username" ]; then echo "Chyba: Uživatelské jméno je povinné." return 1 fi # Zkontroluj jestli Samba uživatel existuje if ! pdbedit -L 2>/dev/null | grep -q "^$username:"; then echo "Chyba: Samba uživatel '$username' neexistuje." echo "Použijte 'user-create' pro vytvoření uživatele." return 1 fi check_config_exists # Zajisti existenci skupiny sambashare ensure_sambashare_group # Přidej uživatele do skupiny sambashare if ! groups "$username" 2>/dev/null | grep -q "sambashare"; then echo "Přidávám uživatele '$username' do skupiny 'sambashare'..." usermod -a -G sambashare "$username" fi # Získej seznam sdílení local shares=($(grep -E "^\[.*\]" "$CONFIG_FILE" | grep -v "\[global\]" | sed 's/\[\(.*\)\]/\1/')) if [ ${#shares[@]} -eq 0 ]; then echo "Žádná sdílení nejsou nakonfigurována." return 1 fi echo "=== NASTAVENÍ PŘÍSTUPU PRO UŽIVATELE '$username' ===" echo "Dostupná sdílení:" local i=1 for share in "${shares[@]}"; do echo " $i) $share" i=$((i+1)) done echo "" echo "Zadejte čísla sdílení oddělená mezerou (např: 1 3 4)" echo -n "Nebo stiskněte Enter pro přístup ke všem: " read selection local selected_shares=() if [ -z "$selection" ]; then selected_shares=("${shares[@]}") else for num in $selection; do if [[ "$num" =~ ^[0-9]+$ ]] && [ "$num" -ge 1 ] && [ "$num" -le ${#shares[@]} ]; then selected_shares+=("${shares[$((num-1))]}") fi done fi if [ ${#selected_shares[@]} -eq 0 ]; then echo "Žádná sdílení nebyla vybrána." return 1 fi echo "" echo "Vytvářím zálohu..." cp "$CONFIG_FILE" "$BACKUP_FILE" # Přidej uživatele do valid users pro vybraná sdílení for share in "${selected_shares[@]}"; do echo "Nastavuji přístup k sdílení: [$share]" # Získej cestu ke sdílení local share_path=$(grep -A 10 "^\[$share\]" "$CONFIG_FILE" | grep "^ path = " | head -1 | sed 's/^ path = //') if [ -n "$share_path" ] && [ -d "$share_path" ]; then # CRITICAL SAFETY: Only modify permissions on safe paths if is_safe_path_for_permissions "$share_path"; then echo " - Nastavuji filesystem oprávnění pro $share_path" chown -R :sambashare "$share_path" 2>/dev/null || true chmod -R g+rw "$share_path" 2>/dev/null || true chmod g+s "$share_path" 2>/dev/null || true # SetGID bit else echo " - ⚠️ PŘESKAKUJI: $share_path je systémový adresář" echo " - Nastavte oprávnění manuálně pokud je potřeba" fi fi # Zkontroluj jestli sdílení má valid users if grep -A 10 "^\[$share\]" "$CONFIG_FILE" | grep -q "^ valid users ="; then # Přidej uživatele k existujícímu valid users sed -i "/^\[$share\]/,/^\[/ s/^ valid users = \(.*\)/ valid users = \1 $username/" "$CONFIG_FILE" else # Přidej nový řádek valid users sed -i "/^\[$share\]/a\ valid users = $username" "$CONFIG_FILE" fi # Odstraň force user pokud existuje (pro multi-user přístup) if grep -A 10 "^\[$share\]" "$CONFIG_FILE" | grep -q "^ force user ="; then echo " - Odstraňuji 'force user' pro podporu více uživatelů" sed -i "/^\[$share\]/,/^\[/ s/^ force user = .*$/ \# force user removed for multi-user access/" "$CONFIG_FILE" fi # Nastav force group na sambashare if grep -A 10 "^\[$share\]" "$CONFIG_FILE" | grep -q "^ force group ="; then sed -i "/^\[$share\]/,/^\[/ s/^ force group = .*/ force group = sambashare/" "$CONFIG_FILE" else sed -i "/^\[$share\]/a\ force group = sambashare" "$CONFIG_FILE" fi # Vypni guest ok pokud je zapnutý sed -i "/^\[$share\]/,/^\[/ s/^ guest ok = yes/ guest ok = no/" "$CONFIG_FILE" echo " ✅ Přístup nastaven" done echo "" echo "✅ Konfigurace dokončena pro sdílení: ${selected_shares[*]}" echo "ℹ️ Uživatel '$username' byl přidán do skupiny 'sambashare'" } # Funkce pro odebrání přístupu uživatele ke sdílení revoke_share_access() { local username="$1" local share_name="$2" if [ -z "$username" ]; then echo -n "Zadejte uživatelské jméno: " read username fi if [ -z "$share_name" ]; then echo -n "Zadejte název sdílení: " read share_name fi if [ -z "$username" ] || [ -z "$share_name" ]; then echo "Chyba: Uživatelské jméno a název sdílení jsou povinné." return 1 fi check_config_exists if ! grep -Fq "[$share_name]" "$CONFIG_FILE"; then echo "Chyba: Sdílení [$share_name] nebylo nalezeno." return 1 fi echo "Vytvářím zálohu..." cp "$CONFIG_FILE" "$BACKUP_FILE" # Odeber uživatele z valid users sed -i "/^\[$share_name\]/,/^\[/ s/\(valid users = .*\) $username/\1/" "$CONFIG_FILE" sed -i "/^\[$share_name\]/,/^\[/ s/valid users = $username \(.*\)/valid users = \1/" "$CONFIG_FILE" sed -i "/^\[$share_name\]/,/^\[/ s/valid users = $username$//" "$CONFIG_FILE" echo "✅ Přístup uživatele '$username' ke sdílení '$share_name' byl odebrán." } # --- Hlavní logika skriptu (Router) --- COMMAND="$1" ARGUMENT1="$2" ARGUMENT2="$3" # Před spuštěním hlavního příkazu vždy aktualizujeme seznam disků discover_mounts # Zpracování parametru --mode=always, který může být na druhé nebo třetí pozici MODE="" if [ "$ARGUMENT1" == "--mode=always" ] || [ "$ARGUMENT2" == "--mode=always" ]; then MODE="always" fi # Hlavní argument je ten, který není --mode=always MAIN_ARG="$ARGUMENT1" if [ "$ARGUMENT1" == "--mode=always" ]; then MAIN_ARG="$ARGUMENT2" fi case "$COMMAND" in mount-share) interactive_mount_and_create "$MODE" test_and_restart ;; create) create_share "$MAIN_ARG" test_and_restart ;; delete) delete_share "$MAIN_ARG" test_and_restart ;; list) list_shares ;; create-all) create_all test_and_restart ;; auto-disks) auto_discover_and_create test_and_restart ;; discover) discover_mounts verbose echo "" echo "Dostupná sdílení pro 'create':" for name in "${!SHARES[@]}"; do IFS='|' read -r path comment type device_name uuid <<< "${SHARES[$name]}" if [ "$type" = "disk" ]; then echo " - $name (cesta: $path, zařízení: /dev/$device_name)" else echo " - $name (cesta: $path)" fi done ;; init) init_config test_and_restart ;; add-global) add_global_section test_and_restart ;; user-create|user-add) create_samba_user "$MAIN_ARG" test_and_restart ;; user-delete|user-remove) delete_samba_user "$MAIN_ARG" ;; user-list) list_samba_users ;; user-access) configure_user_shares "$MAIN_ARG" test_and_restart ;; user-revoke) revoke_share_access "$MAIN_ARG" "$ARGUMENT2" test_and_restart ;; *) echo "FSA - Universal Samba Share Manager" echo "====================================" echo "Použití: sudo $0 {příkaz} [argument]" echo "" echo "Hlavní příkazy:" echo " mount-share [--mode=always] - Interaktivně připojí a nasdílí nepřipojený disk." echo " init - Smaže starou a vytvoří novou, čistou konfiguraci." echo " add-global - Přidá [global] sekci do existující konfigurace." echo "" echo "Správa sdílení:" echo " discover - Najde a zobrazí všechny dostupné disky." echo " auto-disks - Vytvoří sdílení pro všechny AKTUÁLNĚ PŘIPOJENÉ disky." echo " create - Vytvoří sdílení." echo " create-all - Vytvoří statická sdílení (home, root)." echo " delete - Smaže existující sdílení." echo " list - Vypíše nakonfigurovaná sdílení." echo "" echo "Správa uživatelů:" echo " user-create [jméno] - Vytvoří nového Samba uživatele s heslem." echo " user-delete [jméno] - Odstraní Samba uživatele." echo " user-list - Vypíše všechny Samba uživatele." echo " user-access [jméno] - Nastaví přístup uživatele ke sdílením." echo " user-revoke - Odebere přístup uživatele ke sdílení." exit 1 ;; esac