#!/bin/bash # Script to create Samba4 groups from CSV file using ldbmodify # Usage: ./create_samba_groups.sh # Set script directory for relative paths SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" CSV_FILE="$SCRIPT_DIR/Transfert/groups.csv" TEMPLATE_FILE="$SCRIPT_DIR/group.ldif.orig" TEMP_LDIF="$SCRIPT_DIR/group.ldif" # Check if running as root if [[ $EUID -ne 0 ]]; then echo "Error: This script must be run as root to access Samba's LDB database." echo "Please run with: sudo $0" exit 1 fi # Check if required files exist if [[ ! -f "$CSV_FILE" ]]; then echo "Error: CSV file not found at $CSV_FILE" exit 1 fi if [[ ! -f "$TEMPLATE_FILE" ]]; then echo "Error: Template file not found at $TEMPLATE_FILE" exit 1 fi # Check if ldbmodify is available if ! command -v ldbmodify &> /dev/null; then echo "Error: ldbmodify command not found. Please ensure Samba4 is installed." exit 1 fi # Function to clean up temp file cleanup() { if [[ -f "$TEMP_LDIF" ]]; then rm -f "$TEMP_LDIF" echo "Cleaned up temporary file: $TEMP_LDIF" fi } # Set trap to cleanup on exit trap cleanup EXIT # Function to sanitize input (escape special characters for sed) sanitize_for_sed() { local input="$1" # Escape special sed characters: / \ & echo "$input" | sed 's/[\/&\\]/\\&/g' } # Function to validate group data validate_group_data() { local name="$1" local objectsid="$2" # Check for empty fields if [[ -z "$name" || -z "$objectsid" ]]; then return 1 fi # Check ObjectSID format (should start with S-1-5-21) if [[ ! "$objectsid" =~ ^S-1-5-21- ]]; then return 2 fi return 0 } echo "Starting Samba4 group creation process..." echo "Reading groups from: $CSV_FILE" echo "Using template: $TEMPLATE_FILE" echo "" # Counter for statistics total_groups=0 successful_groups=0 failed_groups=0 skipped_groups=0 # Read CSV file line by line (skip header) while IFS=',' read -r NAME OBJECTSID; do # Skip header line if [[ "$NAME" == "NAME" && "$OBJECTSID" == "OBJECTSID" ]]; then continue fi total_groups=$((total_groups + 1)) # Trim whitespace and newlines from variables NAME=$(echo "$NAME" | tr -d '\r\n' | xargs) OBJECTSID=$(echo "$OBJECTSID" | tr -d '\r\n' | xargs) echo "Processing group $total_groups: $NAME" # Validate group data validate_group_data "$NAME" "$OBJECTSID" validation_result=$? case $validation_result in 1) echo " Warning: Skipping group due to missing data (NAME='$NAME', OBJECTSID='$OBJECTSID')" skipped_groups=$((skipped_groups + 1)) continue ;; 2) echo " Warning: Skipping group due to invalid ObjectSID format: $OBJECTSID" skipped_groups=$((skipped_groups + 1)) continue ;; 3) echo " Warning: Skipping group due to invalid name format (contains LDAP special characters): '$NAME'" skipped_groups=$((skipped_groups + 1)) continue ;; esac # Create group.ldif from template by replacing placeholders if ! cp "$TEMPLATE_FILE" "$TEMP_LDIF" 2>/dev/null; then echo " ✗ Failed to copy template file" failed_groups=$((failed_groups + 1)) continue fi # Sanitize inputs for sed NAME_SAFE=$(sanitize_for_sed "$NAME") OBJECTSID_SAFE=$(sanitize_for_sed "$OBJECTSID") # Use sed to replace placeholders with safe inputs sed -i "s/NAME/$NAME_SAFE/g" "$TEMP_LDIF" sed -i "s/OBJECTSID/$OBJECTSID_SAFE/g" "$TEMP_LDIF" echo " Created LDIF file for group: $NAME" # Execute ldbmodify command if ldbmodify -H /var/lib/samba/private/sam.ldb --controls="local_oid:1.3.6.1.4.1.7165.4.3.12:0" "$TEMP_LDIF" 2>/dev/null; then echo " ✓ Successfully created group: $NAME" successful_groups=$((successful_groups + 1)) else echo " ✗ Failed to create group: $NAME" echo " Group may already exist or check Samba permissions." failed_groups=$((failed_groups + 1)) # Try to get more specific error information echo " Attempting to get detailed error..." ldbmodify -H /var/lib/samba/private/sam.ldb --controls="local_oid:1.3.6.1.4.1.7165.4.3.12:0" "$TEMP_LDIF" 2>&1 | head -3 | sed 's/^/ /' fi echo "" done < "$CSV_FILE" # Display final statistics echo "=========================================" echo "Group creation process completed!" echo "Total groups processed: $total_groups" echo "Successfully created: $successful_groups" echo "Failed: $failed_groups" echo "Skipped (validation errors): $skipped_groups" echo "=========================================" # Provide recommendations if [[ $failed_groups -gt 0 ]]; then echo "" echo "Note: If groups failed to be created, possible causes:" echo "1. Group already exists in the domain" echo "2. ObjectSID conflict or duplication" echo "3. Invalid characters in group name" echo "4. Insufficient permissions (already running as root)" echo "5. Samba4 service not running: sudo systemctl status samba-ad-dc" fi # Show created groups if [[ $successful_groups -gt 0 ]]; then echo "" echo "To verify created groups, run:" echo "samba-tool group list | grep -E '$(echo "$CSV_FILE" | xargs -I {} awk -F',' 'NR>1 {print $1}' {} | tr '\n' '|' | sed 's/|$//')'" fi