Fix user permissions - implement group-based multi-user access
Problem: Users could authenticate but got "permission denied" when creating files Root cause: Shares used force_user which prevented proper multi-user access Solution: Group-based permission system - Created `sambashare` group for all Samba users - Users are automatically added to this group on configuration - Share directories get proper group ownership (chown :sambashare) - SetGID bit ensures new files inherit group ownership - Removed force_user directive for multi-user shares - All shares now use force_group=sambashare Changes in configure_user_shares(): - Creates sambashare group if it doesn't exist - Adds user to sambashare group - Sets filesystem permissions: chown -R :sambashare + chmod g+rw - Applies SetGID bit: chmod g+s - Removes force_user from share config - Sets force_group=sambashare Changes in disk share creation: - Creates sambashare group automatically - Adds detected user to sambashare - Sets proper filesystem permissions on mount - Uses force_group=sambashare instead of user's primary group - Removed force_user directive entirely Benefits: ✅ Multiple users can read/write files without permission errors ✅ Files preserve actual creator ownership (not forced) ✅ Proper Unix permissions maintained ✅ Works across reboots (group membership persists) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
68ea576205
commit
63fa3c6636
2 changed files with 83 additions and 6 deletions
21
README.md
21
README.md
|
|
@ -101,7 +101,11 @@ sudo ./spravuj_sdileni.sh user-list
|
||||||
```bash
|
```bash
|
||||||
sudo ./spravuj_sdileni.sh user-access [username]
|
sudo ./spravuj_sdileni.sh user-access [username]
|
||||||
```
|
```
|
||||||
Interactively select which shares the user can access.
|
Interactively select which shares the user can access. This command:
|
||||||
|
- Adds the user to the `sambashare` group
|
||||||
|
- Sets proper filesystem permissions (group ownership + read/write)
|
||||||
|
- Removes single-user restrictions (`force user`) from shares
|
||||||
|
- Enables multi-user access with proper file ownership
|
||||||
|
|
||||||
**Revoke user access from a share**:
|
**Revoke user access from a share**:
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -114,6 +118,21 @@ sudo ./spravuj_sdileni.sh user-delete [username]
|
||||||
```
|
```
|
||||||
Optionally removes the system user as well.
|
Optionally removes the system user as well.
|
||||||
|
|
||||||
|
### How Permissions Work
|
||||||
|
|
||||||
|
FSA uses a group-based permission system for secure multi-user access:
|
||||||
|
|
||||||
|
1. **sambashare Group**: All Samba users are added to this group
|
||||||
|
2. **Filesystem Permissions**: Share directories are owned by group `sambashare` with read/write access
|
||||||
|
3. **SetGID Bit**: Ensures new files inherit the correct group ownership
|
||||||
|
4. **No Force User**: Multi-user shares don't force a specific user, preserving actual file ownership
|
||||||
|
|
||||||
|
This means:
|
||||||
|
- ✅ Multiple users can read/write files
|
||||||
|
- ✅ Files show the actual creator's ownership
|
||||||
|
- ✅ Proper Unix permissions are maintained
|
||||||
|
- ✅ No permission denied errors
|
||||||
|
|
||||||
## Share Types
|
## Share Types
|
||||||
|
|
||||||
The script creates different types of shares:
|
The script creates different types of shares:
|
||||||
|
|
|
||||||
|
|
@ -229,6 +229,13 @@ EOT
|
||||||
echo "Základní konfigurace vytvořena."
|
echo "Základní konfigurace vytvořena."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Funkce pro zajištění existence skupiny sambashare
|
||||||
|
ensure_sambashare_group() {
|
||||||
|
if ! getent group sambashare > /dev/null 2>&1; then
|
||||||
|
groupadd sambashare 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# OPRAVENÁ FUNKCE: Vytvoří sdílení se správným formátováním a `force user`
|
# OPRAVENÁ FUNKCE: Vytvoří sdílení se správným formátováním a `force user`
|
||||||
create_share() {
|
create_share() {
|
||||||
local share_name="$1"
|
local share_name="$1"
|
||||||
|
|
@ -277,16 +284,30 @@ EOT
|
||||||
;;
|
;;
|
||||||
"disk")
|
"disk")
|
||||||
local dfree_script=$(create_dfree_script "$share_path")
|
local dfree_script=$(create_dfree_script "$share_path")
|
||||||
local PRIMARY_GROUP=$(id -gn "$DETECTED_USER")
|
|
||||||
|
# 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
|
||||||
|
if [ -d "$share_path" ]; then
|
||||||
|
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
|
||||||
|
fi
|
||||||
|
|
||||||
cat <<EOT >> "$CONFIG_FILE"
|
cat <<EOT >> "$CONFIG_FILE"
|
||||||
|
|
||||||
[$share_name]
|
[$share_name]
|
||||||
path = $share_path
|
path = $share_path
|
||||||
force user = $DETECTED_USER
|
|
||||||
writable = yes
|
writable = yes
|
||||||
guest ok = no
|
guest ok = no
|
||||||
valid users = $DETECTED_USER
|
valid users = $DETECTED_USER
|
||||||
force group = $PRIMARY_GROUP
|
force group = sambashare
|
||||||
create mask = 0664
|
create mask = 0664
|
||||||
directory mask = 0775
|
directory mask = 0775
|
||||||
dfree command = $dfree_script
|
dfree command = $dfree_script
|
||||||
|
|
@ -754,6 +775,15 @@ configure_user_shares() {
|
||||||
|
|
||||||
check_config_exists
|
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í
|
# Získej seznam sdílení
|
||||||
local shares=($(grep -E "^\[.*\]" "$CONFIG_FILE" | grep -v "\[global\]" | sed 's/\[\(.*\)\]/\1/'))
|
local shares=($(grep -E "^\[.*\]" "$CONFIG_FILE" | grep -v "\[global\]" | sed 's/\[\(.*\)\]/\1/'))
|
||||||
|
|
||||||
|
|
@ -797,7 +827,18 @@ configure_user_shares() {
|
||||||
|
|
||||||
# Přidej uživatele do valid users pro vybraná sdílení
|
# Přidej uživatele do valid users pro vybraná sdílení
|
||||||
for share in "${selected_shares[@]}"; do
|
for share in "${selected_shares[@]}"; do
|
||||||
echo "Přidávám přístup k sdílení: [$share]"
|
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
|
||||||
|
# Nastav filesystem permissions
|
||||||
|
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
|
||||||
|
fi
|
||||||
|
|
||||||
# Zkontroluj jestli sdílení má valid users
|
# Zkontroluj jestli sdílení má valid users
|
||||||
if grep -A 10 "^\[$share\]" "$CONFIG_FILE" | grep -q "^ valid users ="; then
|
if grep -A 10 "^\[$share\]" "$CONFIG_FILE" | grep -q "^ valid users ="; then
|
||||||
|
|
@ -808,11 +849,28 @@ configure_user_shares() {
|
||||||
sed -i "/^\[$share\]/a\ valid users = $username" "$CONFIG_FILE"
|
sed -i "/^\[$share\]/a\ valid users = $username" "$CONFIG_FILE"
|
||||||
fi
|
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ý
|
# Vypni guest ok pokud je zapnutý
|
||||||
sed -i "/^\[$share\]/,/^\[/ s/^ guest ok = yes/ guest ok = no/" "$CONFIG_FILE"
|
sed -i "/^\[$share\]/,/^\[/ s/^ guest ok = yes/ guest ok = no/" "$CONFIG_FILE"
|
||||||
|
|
||||||
|
echo " ✅ Přístup nastaven"
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "✅ Přístup nastaven pro sdílení: ${selected_shares[*]}"
|
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í
|
# Funkce pro odebrání přístupu uživatele ke sdílení
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue