Guide

Nouvelles mises à jour et améliorations de Roundfleet.

Gestion de Réseau Wi-Fi sur macOS

Déployez et gérez des configurations réseau Wi-Fi complètes sur vos appareils Roundfleet. Ce tutoriel couvre la gestion de politiques réseau, configurations de sécurité, paramètres proxy, gestion DNS et stratégies de déploiement de niveau entreprise.

Comprendre la Gestion Réseau macOS

macOS fournit des outils de ligne de commande puissants pour la gestion réseau :

  • networksetup - Outil principal pour la configuration réseau
  • airport - Scan et gestion Wi-Fi avancés
  • scutil - Utilitaire de configuration système pour les paramètres réseau
  • Profils réseau - Gestion réseau basée sur les politiques d'entreprise

Opérations Wi-Fi Basiques

Activer/Désactiver l'Interface Wi-Fi

#!/bin/bash

# Activer l'interface Wi-Fi
enable_wifi() {
    echo "Activation de l'interface Wi-Fi..."
    networksetup -setairportpower en0 on
    
    if [[ $? -eq 0 ]]; then
        echo "✅ Interface Wi-Fi activée avec succès"
        return 0
    else
        echo "❌ Échec de l'activation de l'interface Wi-Fi"
        return 1
    fi
}

# Désactiver l'interface Wi-Fi
disable_wifi() {
    echo "⚠️  Désactivation de l'interface Wi-Fi..."
    echo "Assurez-vous que l'appareil a une connectivité alternative (Ethernet, etc.)"
    
    networksetup -setairportpower en0 off
    
    if [[ $? -eq 0 ]]; then
        echo "✅ Interface Wi-Fi désactivée avec succès"
        return 0
    else
        echo "❌ Échec de la désactivation de l'interface Wi-Fi"
        return 1
    fi
}

# Utilisation
enable_wifi

Activer/Désactiver le Service Wi-Fi

#!/bin/bash

# Activer le service Wi-Fi
turn_wifi_on() {
    echo "Activation du service Wi-Fi..."
    networksetup -setnetworkserviceenabled Wi-Fi on
    
    if [[ $? -eq 0 ]]; then
        echo "✅ Service Wi-Fi activé"
        return 0
    else
        echo "❌ Échec de l'activation du service Wi-Fi"
        return 1
    fi
}

# Vérifier le statut du service Wi-Fi
check_wifi_service() {
    echo "Vérification du statut du service Wi-Fi..."
    local status
    status=$(networksetup -getnetworkserviceenabled Wi-Fi)
    
    echo "Statut du service Wi-Fi : $status"
    return 0
}

# Utilisation
check_wifi_service
turn_wifi_on

Informations Réseau Wi-Fi

Obtenir les Informations Réseau Actuelles

#!/bin/bash

# Obtenir le SSID du réseau Wi-Fi actuel
get_current_network() {
    echo "=== Réseau Wi-Fi Actuel ==="
    local network_info
    network_info=$(networksetup -getairportnetwork en0)
    
    if [[ "$network_info" == *"not associated"* ]]; then
        echo "❌ Non connecté à un réseau Wi-Fi"
        return 1
    else
        echo "📶 $network_info"
        return 0
    fi
}

# Obtenir des informations Wi-Fi complètes
get_wifi_info() {
    echo "=== Informations Réseau Wi-Fi ==="
    networksetup -getinfo Wi-Fi
    
    echo -e "\n=== Détails de l'Interface Wi-Fi ==="
    ifconfig en0 | grep -E "(inet |ether |status)"
    
    echo -e "\n=== Qualité Wi-Fi ==="
    /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I
}

# Scanner les réseaux disponibles
scan_networks() {
    echo "=== Réseaux Wi-Fi Disponibles ==="
    /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -s
}

# Utilisation
get_current_network
echo ""
get_wifi_info

Système de Gestion Wi-Fi d'Entreprise

#!/bin/bash

# Système de Gestion Wi-Fi d'Entreprise Roundfleet
# Configuration Wi-Fi centralisée et gestion de politiques pour appareils de flotte

# Configuration
LOG_FILE="/var/log/roundfleet_wifi.log"
CONFIG_DIR="/etc/roundfleet/wifi"
PROFILES_DIR="$CONFIG_DIR/profiles"
BACKUP_DIR="/var/backups/network_configs"

# Modèles de profils réseau
declare -A NETWORK_PROFILES=(
    ["entreprise"]="security=WPA2Enterprise,proxy=auto,dns=entreprise"
    ["invite"]="security=WPA2Personal,proxy=none,dns=public"
    ["securise"]="security=WPA2Enterprise,proxy=obligatoire,dns=securise"
    ["developpement"]="security=WPA2Personal,proxy=bypass,dns=dev"
    ["public"]="security=none,proxy=auto,dns=public"
)

# Configurations serveurs DNS
declare -A DNS_CONFIGS=(
    ["entreprise"]="10.0.1.1 10.0.1.2"
    ["public"]="8.8.8.8 8.8.4.4"
    ["securise"]="1.1.1.1 1.0.0.1"
    ["dev"]="192.168.1.1 8.8.8.8"
)

# Fonction de journalisation
log_action() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}

# Configurer les serveurs DNS
configure_dns() {
    local dns_profile="$1"
    local custom_dns="$2"
    
    log_action "Configuration des serveurs DNS : $dns_profile"
    
    local dns_servers
    if [[ -n "$custom_dns" ]]; then
        dns_servers="$custom_dns"
    else
        dns_servers="${DNS_CONFIGS[$dns_profile]}"
    fi
    
    if [[ -z "$dns_servers" ]]; then
        log_action "❌ Profil DNS inconnu ou configuration vide : $dns_profile"
        return 1
    fi
    
    # Configurer les serveurs DNS
    if networksetup -setdnsservers Wi-Fi $dns_servers; then
        log_action "✅ Serveurs DNS configurés : $dns_servers"
        
        # Vérifier la configuration
        local current_dns
        current_dns=$(networksetup -getdnsservers Wi-Fi)
        log_action "Serveurs DNS actuels : $current_dns"
        
        return 0
    else
        log_action "❌ Échec de la configuration des serveurs DNS"
        return 1
    fi
}

# Configurer les domaines de recherche
configure_search_domains() {
    local domains="$*"
    
    if [[ -z "$domains" ]]; then
        log_action "Effacement des domaines de recherche"
        networksetup -setsearchdomains Wi-Fi "Empty"
    else
        log_action "Configuration des domaines de recherche : $domains"
        networksetup -setsearchdomains Wi-Fi $domains
    fi
    
    if [[ $? -eq 0 ]]; then
        log_action "✅ Domaines de recherche configurés avec succès"
        return 0
    else
        log_action "❌ Échec de la configuration des domaines de recherche"
        return 1
    fi
}

# Configurer le proxy web
configure_web_proxy() {
    local proxy_type="$1"
    local proxy_config="$2"
    
    log_action "Configuration du proxy web : $proxy_type"
    
    case "$proxy_type" in
        "none")
            # Désactiver tous les proxies
            networksetup -setwebproxystate Wi-Fi off
            networksetup -setsecurewebproxystate Wi-Fi off
            networksetup -setautoproxystate Wi-Fi off
            log_action "✅ Tous les proxies désactivés"
            ;;
        "web")
            local proxy_server proxy_port auth_required username password
            IFS=':' read -ra PROXY_PARTS <<< "$proxy_config"
            proxy_server="${PROXY_PARTS[0]}"
            proxy_port="${PROXY_PARTS[1]}"
            auth_required="${PROXY_PARTS[2]}"
            username="${PROXY_PARTS[3]:-}"
            password="${PROXY_PARTS[4]:-}"
            
            if [[ "$auth_required" == "authenticated" && -n "$username" && -n "$password" ]]; then
                networksetup -setwebproxy Wi-Fi "$proxy_server" "$proxy_port" on "$username" "$password"
            else
                networksetup -setwebproxy Wi-Fi "$proxy_server" "$proxy_port" off
            fi
            
            networksetup -setwebproxystate Wi-Fi on
            log_action "✅ Proxy web configuré : $proxy_server:$proxy_port"
            ;;
        "auto")
            networksetup -setautoproxyurl Wi-Fi "$proxy_config"
            networksetup -setautoproxystate Wi-Fi on
            log_action "✅ Proxy automatique configuré : $proxy_config"
            ;;
        *)
            log_action "❌ Type de proxy inconnu : $proxy_type"
            return 1
            ;;
    esac
    
    return 0
}

# Sauvegarder la configuration réseau actuelle
backup_network_config() {
    local backup_timestamp
    backup_timestamp=$(date '+%Y%m%d_%H%M%S')
    local backup_file="$BACKUP_DIR/network_config_$backup_timestamp.tar.gz"
    
    log_action "Création de la sauvegarde de configuration réseau : $backup_file"
    
    # Créer un répertoire de sauvegarde temporaire
    local temp_backup="/tmp/network_backup_$$"
    mkdir -p "$temp_backup"
    
    # Exporter les paramètres actuels
    {
        echo "# Statut du Service Wi-Fi"
        networksetup -getnetworkserviceenabled Wi-Fi
        
        echo -e "\n# Statut d'Alimentation Wi-Fi"
        networksetup -getairportpower en0
        
        echo -e "\n# Réseau Actuel"
        networksetup -getairportnetwork en0
        
        echo -e "\n# Informations Réseau"
        networksetup -getinfo Wi-Fi
        
        echo -e "\n# Serveurs DNS"
        networksetup -getdnsservers Wi-Fi
        
        echo -e "\n# Domaines de Recherche"
        networksetup -getsearchdomains Wi-Fi
        
        echo -e "\n# Proxy Web"
        networksetup -getwebproxy Wi-Fi
        
    } > "$temp_backup/current_config.txt"
    
    # Créer une sauvegarde compressée
    if tar -czf "$backup_file" -C "$(dirname "$temp_backup")" "$(basename "$temp_backup")" 2>/dev/null; then
        log_action "✅ Sauvegarde réseau créée : $backup_file"
        rm -rf "$temp_backup"
        echo "$backup_file"
        return 0
    else
        log_action "❌ Échec de la sauvegarde réseau"
        rm -rf "$temp_backup"
        return 1
    fi
}

# Diagnostics réseau
network_diagnostics() {
    echo "=== Diagnostics Réseau Roundfleet ==="
    echo "Horodatage : $(date)"
    echo "Nom d'hôte : $(hostname)"
    echo "======================================="
    
    # Statut de l'interface Wi-Fi
    echo -e "\n🔍 Statut de l'Interface Wi-Fi :"
    local wifi_power
    wifi_power=$(networksetup -getairportpower en0)
    echo "Alimentation : $wifi_power"
    
    local wifi_service
    wifi_service=$(networksetup -getnetworkserviceenabled Wi-Fi)
    echo "Service : $wifi_service"
    
    # Connexion actuelle
    echo -e "\n📶 Connexion Actuelle :"
    networksetup -getairportnetwork en0
    
    # Configuration réseau
    echo -e "\n⚙️  Configuration Réseau :"
    networksetup -getinfo Wi-Fi
    
    # Paramètres DNS
    echo -e "\n🌐 Paramètres DNS :"
    networksetup -getdnsservers Wi-Fi
    
    # Test de connectivité
    echo -e "\n🌍 Test de Connectivité :"
    if ping -c 3 8.8.8.8 >/dev/null 2>&1; then
        echo "✅ Connectivité Internet : Disponible"
    else
        echo "❌ Connectivité Internet : Échec"
    fi
    
    if ping -c 3 apple.com >/dev/null 2>&1; then
        echo "✅ Résolution DNS : Fonctionne"
    else
        echo "❌ Résolution DNS : Échec"
    fi
}

# Fonction d'exécution principale
main() {
    local action="${1:-status}"
    local profile_name="$2"
    local additional_param="$3"
    
    log_action "=== Démarrage de la Gestion Wi-Fi Roundfleet ==="
    log_action "Action : $action"
    log_action "Profil : ${profile_name:-N/A}"
    
    case "$action" in
        "status")
            network_diagnostics
            ;;
        "dns")
            if [[ -z "$profile_name" ]]; then
                echo "Profils DNS disponibles : ${!DNS_CONFIGS[*]}"
                echo "Usage : $0 dns <nom_profil|serveurs_personnalisés>"
                exit 1
            fi
            configure_dns "$profile_name" "$additional_param"
            ;;
        "proxy")
            if [[ -z "$profile_name" ]]; then
                echo "Usage : $0 proxy <none|web|auto> [config]"
                exit 1
            fi
            configure_web_proxy "$profile_name" "$additional_param"
            ;;
        "backup")
            backup_network_config
            ;;
        *)
            echo "Usage : $0 {status|dns|proxy|backup}"
            echo "  status  - Afficher le statut et diagnostics réseau"
            echo "  dns     - Configurer les serveurs DNS"
            echo "  proxy   - Configurer les paramètres proxy"
            echo "  backup  - Sauvegarder la configuration réseau actuelle"
            exit 1
            ;;
    esac
    
    log_action "=== Gestion Wi-Fi terminée ==="
}

# Exécuter la fonction principale
main "$@"

Configuration Réseau Avancée

Gestion de Profils Wi-Fi d'Entreprise

#!/bin/bash

# Créer un profil réseau personnalisé
create_network_profile() {
    local profile_name="$1"
    local ssid="$2"
    local security_type="$3"
    local proxy_config="$4"
    local dns_config="$5"
    
    local profile_file="$PROFILES_DIR/${profile_name}.json"
    
    cat > "$profile_file" << EOF
{
    "profile_name": "$profile_name",
    "created_date": "$(date -Iseconds)",
    "wifi_settings": {
        "ssid": "$ssid",
        "security_type": "$security_type",
        "auto_connect": true,
        "priority": 100
    },
    "proxy_settings": {
        "type": "$proxy_config",
        "bypass_domains": ["*.local", "localhost"]
    },
    "dns_settings": {
        "servers": "$dns_config",
        "search_domains": ["company.com", "local"]
    }
}
EOF

    echo "Profil réseau créé : $profile_file"
}

Surveillance de Qualité Réseau

#!/bin/bash

# Surveiller la qualité et performance réseau
monitor_network_quality() {
    local duration="${1:-60}"  # durée de surveillance en secondes
    local interval="${2:-5}"   # intervalle de vérification en secondes
    
    echo "=== Surveillance de Qualité Réseau ==="
    echo "Durée : ${duration}s, Intervalle : ${interval}s"
    
    local start_time end_time
    start_time=$(date +%s)
    end_time=$((start_time + duration))
    
    while [[ $(date +%s) -lt $end_time ]]; do
        local timestamp signal_strength tx_rate
        timestamp=$(date '+%H:%M:%S')
        
        # Obtenir les métriques Wi-Fi
        local airport_info
        airport_info=$(/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I)
        
        signal_strength=$(echo "$airport_info" | grep 'RSSI:' | awk '{print $2}')
        tx_rate=$(echo "$airport_info" | grep 'lastTxRate:' | awk '{print $2}')
        
        # Tester la vitesse de connectivité
        local ping_time
        ping_time=$(ping -c 1 8.8.8.8 2>/dev/null | grep 'time=' | awk -F'time=' '{print $2}' | awk '{print $1}')
        
        printf "%s | Signal: %sdBm | Vitesse: %sMbps | Ping: %s\n" \
               "$timestamp" "$signal_strength" "$tx_rate" "${ping_time:-timeout}"
        
        sleep "$interval"
    done
}

Sécurité et Conformité

Audit de Sécurité Réseau

#!/bin/bash

# Audit complet de sécurité réseau
network_security_audit() {
    echo "=== Audit de Sécurité Réseau ==="
    log_action "Démarrage de l'audit de sécurité réseau"
    
    # Vérifier le chiffrement Wi-Fi
    local wifi_encryption
    wifi_encryption=$(networksetup -getairportnetwork en0 | grep -o 'WPA\\|WEP\\|None' || echo 'Inconnu')
    echo "Chiffrement Wi-Fi : $wifi_encryption"
    
    # Vérifier le statut du proxy
    local proxy_enabled
    proxy_enabled=$(networksetup -getwebproxystate Wi-Fi)
    echo "Proxy activé : $proxy_enabled"
    
    # Vérifier les serveurs DNS
    local dns_servers
    dns_servers=$(networksetup -getdnsservers Wi-Fi)
    echo "Serveurs DNS : $dns_servers"
    
    # Recommandations de sécurité
    echo -e "\n=== Recommandations de Sécurité ==="
    
    if [[ "$wifi_encryption" == "None" ]]; then
        echo "⚠️  Évitez les réseaux non chiffrés"
    fi
    
    if echo "$dns_servers" | grep -q "There aren't any DNS Servers"; then
        echo "⚠️  Configurez des serveurs DNS sécurisés"
    fi
    
    log_action "✅ Audit de sécurité terminé"
}

Application de Politiques de Conformité

#!/bin/bash

# Appliquer les politiques de conformité d'entreprise
enforce_compliance_policy() {
    local policy_name="$1"
    
    log_action "Application de la politique de conformité : $policy_name"
    
    case "$policy_name" in
        "entreprise")
            # Politique d'entreprise : DNS sécurisé, proxy obligatoire
            configure_dns "entreprise"
            configure_web_proxy "web" "proxy.company.com:8080:authenticated"
            ;;
        "education")
            # Politique éducation : DNS sûr, proxy de filtrage de contenu
            configure_dns "public"
            configure_web_proxy "auto" "http://filter.school.edu/proxy.pac"
            ;;
        "sante")
            # Politique santé : paramètres conformes HIPAA
            configure_dns "securise"
            configure_web_proxy "web" "secure-proxy.hospital.org:8080:authenticated"
            ;;
        *)
            log_action "❌ Politique de conformité inconnue : $policy_name"
            return 1
            ;;
    esac
    
    log_action "✅ Politique de conformité appliquée : $policy_name"
    return 0
}

Dépannage Réseau

Réparation Réseau Automatisée

#!/bin/bash

# Dépannage et réparation réseau automatisés
network_repair() {
    local repair_level="${1:-basic}"
    
    log_action "Démarrage de la réparation réseau : $repair_level"
    
    echo "=== Réparation Réseau Roundfleet ==="
    
    # Test de connectivité de base
    echo "🔍 Test de connectivité de base..."
    if ping -c 3 8.8.8.8 >/dev/null 2>&1; then
        echo "✅ Connectivité Internet : OK"
    else
        echo "❌ Connectivité Internet : ÉCHEC"
        
        case "$repair_level" in
            "basic")
                echo "🔧 Tentative de réparation de base..."
                # Redémarrer Wi-Fi
                networksetup -setairportpower en0 off
                sleep 3
                networksetup -setairportpower en0 on
                sleep 5
                ;;
            "avance")
                echo "🔧 Tentative de réparation avancée..."
                # Réinitialisation réseau complète
                configure_dns "public"
                configure_web_proxy "none"
                networksetup -setairportpower en0 off
                sleep 3
                networksetup -setairportpower en0 on
                sleep 10
                ;;
        esac
        
        # Re-tester après réparation
        echo "🔄 Nouveau test de connectivité..."
        if ping -c 3 8.8.8.8 >/dev/null 2>&1; then
            echo "✅ Réparation réussie"
            log_action "Réparation réseau réussie : $repair_level"
        else
            echo "❌ Réparation échouée - escalader vers intervention manuelle"
            log_action "Réparation réseau échouée : $repair_level"
        fi
    fi
}

Meilleures Pratiques

🚀 Optimisation des Performances

  • Surveillez la qualité réseau régulièrement et basculez vers les réseaux optimaux
  • Configurez des tailles MTU appropriées pour votre environnement réseau
  • Utilisez la mise en cache DNS locale pour améliorer les vitesses de résolution
  • Optimisez les paramètres proxy pour votre cas d'usage spécifique

🔐 Directives de Sécurité

  • Utilisez toujours des réseaux chiffrés (WPA2/WPA3) dans les environnements d'entreprise
  • Configurez des serveurs DNS sécurisés pour prévenir l'empoisonnement DNS
  • Implémentez des politiques proxy pour le filtrage de contenu et la sécurité
  • Audits de sécurité réguliers pour identifier les vulnérabilités réseau

📋 Meilleures Pratiques de Gestion

  • Configuration basée sur les profils pour différents groupes d'utilisateurs et emplacements
  • Application de politiques centralisées sur tous les appareils de flotte
  • Sauvegarde régulière des configurations réseau avant les changements
  • Surveillance et alertes automatisées pour les problèmes de connectivité

🔍 Conseils de Dépannage

  • Utilisez les diagnostics réseau pour identifier les problèmes de configuration
  • Surveillez la force du signal et les métriques de qualité réseau
  • Testez la connectivité vers plusieurs points de terminaison pour une validation complète
  • Documentez les changements réseau pour les pistes d'audit et le dépannage

Notes Importantes

  • Les changements réseau prennent effet immédiatement mais peuvent nécessiter une reconnexion
  • Les identifiants d'authentification proxy doivent être gérés de manière sécurisée
  • Les changements DNS peuvent nécessiter un vidage du cache pour prendre effet
  • Certains réseaux d'entreprise nécessitent des certificats spécifiques pour l'authentification
  • Toujours sauvegarder les configurations avant de faire des changements significatifs

Contrôle Wi-Fi d'Entreprise sur macOS

Contrôlez et gérez les paramètres Wi-Fi sur vos appareils Roundfleet en utilisant des outils de ligne de commande avancés et des politiques sans fil centralisées. Ce tutoriel couvre la gestion de l'alimentation Wi-Fi, le contrôle des connexions, l'application de la sécurité et la gestion de réseau sans fil de niveau entreprise avec des capacités complètes de surveillance et de conformité.

Comprendre la Gestion Wi-Fi macOS

macOS fournit plusieurs outils de ligne de commande pour la gestion Wi-Fi :

  • networksetup - Outil principal pour la configuration et le contrôle réseau
  • airport - Utilitaire de gestion d'interface sans fil de bas niveau
  • ifconfig - Outil de configuration d'interface réseau
  • Préférences Système - Équivalent GUI pour les paramètres sans fil

Le contrôle Wi-Fi d'entreprise nécessite une attention particulière aux politiques de sécurité, à la gestion de l'alimentation et aux exigences de conformité.

Commandes de Contrôle Wi-Fi de Base

Désactiver le Wi-Fi

#!/bin/bash

# Commande de base pour désactiver le Wi-Fi
turn_off_wifi_basic() {
    # Obtenir le nom de l'interface airport
    local AIRPORT=$(networksetup -listallhardwareports | grep -A 1 Wi-Fi | grep Device | awk '{print $2}')
    
    if [[ -n "$AIRPORT" ]]; then
        networksetup -setairportpower "$AIRPORT" off
        
        if [[ $? -eq 0 ]]; then
            echo "✅ Wi-Fi désactivé avec succès"
            return 0
        else
            echo "❌ Échec de la désactivation du Wi-Fi"
            return 1
        fi
    else
        echo "❌ Interface Wi-Fi non trouvée"
        return 1
    fi
}

# Exemple d'utilisation
turn_off_wifi_basic

Activer le Wi-Fi

#!/bin/bash

# Activer le Wi-Fi avec vérification
turn_on_wifi() {
    local interface_name="$1"
    
    # Détection automatique de l'interface si non fournie
    if [[ -z "$interface_name" ]]; then
        interface_name=$(networksetup -listallhardwareports | grep -A 1 Wi-Fi | grep Device | awk '{print $2}')
    fi
    
    if [[ -z "$interface_name" ]]; then
        echo "❌ Interface Wi-Fi non trouvée"
        return 1
    fi
    
    echo "Activation de l'interface Wi-Fi : $interface_name"
    networksetup -setairportpower "$interface_name" on
    
    # Attendre que l'interface soit active
    sleep 3
    
    # Vérifier que le Wi-Fi est activé
    local wifi_status
    wifi_status=$(networksetup -getairportpower "$interface_name" | grep "On")
    
    if [[ -n "$wifi_status" ]]; then
        echo "✅ Wi-Fi activé avec succès"
        return 0
    else
        echo "❌ Échec de l'activation du Wi-Fi"
        return 1
    fi
}

# Exemple d'utilisation
# turn_on_wifi "en0"

Vérifier le Statut Wi-Fi

#!/bin/bash

# Vérifier le statut Wi-Fi actuel avec informations détaillées
check_wifi_status() {
    echo "=== Rapport de Statut Wi-Fi ==="
    echo "Généré : $(date)"
    echo "==============================="
    echo ""
    
    # Obtenir toutes les interfaces Wi-Fi
    local wifi_interfaces
    wifi_interfaces=$(networksetup -listallhardwareports | grep -A 1 Wi-Fi | grep Device | awk '{print $2}')
    
    if [[ -z "$wifi_interfaces" ]]; then
        echo "❌ Aucune interface Wi-Fi trouvée"
        return 1
    fi
    
    for interface in $wifi_interfaces; do
        echo "Interface : $interface"
        echo "-----------------"
        
        # Statut d'alimentation
        local power_status
        power_status=$(networksetup -getairportpower "$interface")
        echo "Statut d'Alimentation : $power_status"
        
        # Statut de connexion
        if echo "$power_status" | grep -q "On"; then
            # Obtenir le réseau actuel
            local current_network
            current_network=$(networksetup -getairportnetwork "$interface" | cut -d' ' -f4-)
            echo "Réseau Actuel : $current_network"
            
            # Obtenir l'adresse IP si connecté
            local ip_address
            ip_address=$(ifconfig "$interface" | grep "inet " | awk '{print $2}')
            if [[ -n "$ip_address" ]]; then
                echo "Adresse IP : $ip_address"
            else
                echo "Adresse IP : Non assignée"
            fi
            
            # Force du signal (si disponible)
            if command -v airport >/dev/null 2>&1; then
                local signal_info
                signal_info=$(airport -I | grep "agrCtlRSSI" | awk '{print $2}')
                if [[ -n "$signal_info" ]]; then
                    echo "Force du Signal : $signal_info dBm"
                fi
            fi
        else
            echo "Wi-Fi désactivé"
        fi
        
        echo ""
    done
}

# Exécuter la vérification de statut
check_wifi_status

Système de Contrôle Wi-Fi d'Entreprise

#!/bin/bash

# Système de Contrôle Wi-Fi d'Entreprise Roundfleet
# Gestion sans fil complète, application de sécurité et surveillance de conformité

# Configuration
LOG_FILE="/var/log/roundfleet_wifi_control.log"
CONFIG_FILE="/etc/roundfleet/wifi_config.conf"
BACKUP_DIR="/var/backups/roundfleet/wifi"
POLICY_DIR="/etc/roundfleet/wifi_policies"

# Créer la structure de répertoires
setup_directories() {
    mkdir -p "$(dirname "$LOG_FILE")" "$BACKUP_DIR" "$POLICY_DIR" "$(dirname "$CONFIG_FILE")"
    touch "$LOG_FILE"
    
    # Définir les permissions appropriées
    chmod 755 "$BACKUP_DIR" "$POLICY_DIR"
}

# Fonction de journalisation
log_action() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}

# Application de politique Wi-Fi d'entreprise
enforce_wifi_policy() {
    local policy_name="$1"
    local policy_file="$POLICY_DIR/${policy_name}.policy"
    
    if [[ ! -f "$policy_file" ]]; then
        log_action "ERREUR : Politique Wi-Fi non trouvée : $policy_name"
        return 1
    fi
    
    log_action "Application de la politique Wi-Fi : $policy_name"
    
    # Charger la configuration de politique
    source "$policy_file"
    
    # Obtenir l'interface Wi-Fi
    local wifi_interface
    wifi_interface=$(networksetup -listallhardwareports | grep -A 1 Wi-Fi | grep Device | awk '{print $2}')
    
    if [[ -z "$wifi_interface" ]]; then
        log_action "ERREUR : Aucune interface Wi-Fi trouvée"
        return 1
    fi
    
    # Appliquer les paramètres de politique
    case "${WIFI_POLICY_ACTION:-disable}" in
        "disable")
            networksetup -setairportpower "$wifi_interface" off
            log_action "Wi-Fi désactivé selon la politique : $policy_name"
            ;;
        "enable")
            networksetup -setairportpower "$wifi_interface" on
            log_action "Wi-Fi activé selon la politique : $policy_name"
            ;;
        "scheduled")
            apply_scheduled_wifi_policy "$wifi_interface" "$policy_name"
            ;;
        "conditional")
            apply_conditional_wifi_policy "$wifi_interface" "$policy_name"
            ;;
        *)
            log_action "ERREUR : Action de politique inconnue : ${WIFI_POLICY_ACTION}"
            return 1
            ;;
    esac
    
    return 0
}

# Contrôle Wi-Fi programmé
apply_scheduled_wifi_policy() {
    local interface="$1"
    local policy_name="$2"
    local current_hour=$(date +%H)
    local current_day=$(date +%u)  # 1=Lundi, 7=Dimanche
    
    log_action "Application de la politique Wi-Fi programmée : $policy_name"
    
    # Charger le planning depuis la politique
    local enable_hours="${WIFI_ENABLE_HOURS:-09-17}"
    local enable_days="${WIFI_ENABLE_DAYS:-1-5}"
    
    # Analyser la plage horaire
    local start_hour end_hour
    start_hour=$(echo "$enable_hours" | cut -d'-' -f1)
    end_hour=$(echo "$enable_hours" | cut -d'-' -f2)
    
    # Analyser la plage de jours
    local start_day end_day
    start_day=$(echo "$enable_days" | cut -d'-' -f1)
    end_day=$(echo "$enable_days" | cut -d'-' -f2)
    
    # Vérifier si l'heure actuelle est dans la fenêtre autorisée
    local time_allowed=false
    local day_allowed=false
    
    if [[ "$current_hour" -ge "$start_hour" && "$current_hour" -lt "$end_hour" ]]; then
        time_allowed=true
    fi
    
    if [[ "$current_day" -ge "$start_day" && "$current_day" -le "$end_day" ]]; then
        day_allowed=true
    fi
    
    if [[ "$time_allowed" == "true" && "$day_allowed" == "true" ]]; then
        networksetup -setairportpower "$interface" on
        log_action "Wi-Fi activé - dans les heures programmées"
    else
        networksetup -setairportpower "$interface" off
        log_action "Wi-Fi désactivé - hors des heures programmées"
    fi
}

# Contrôle Wi-Fi conditionnel
apply_conditional_wifi_policy() {
    local interface="$1"
    local policy_name="$2"
    
    log_action "Application de la politique Wi-Fi conditionnelle : $policy_name"
    
    # Vérifier le niveau de batterie
    local battery_level
    battery_level=$(pmset -g batt | grep -o '[0-9]*%' | tr -d '%')
    
    # Vérifier la source d'alimentation
    local power_source
    power_source=$(pmset -g ps | head -1 | grep -o "'.*'" | tr -d "'")
    
    # Vérifier la connexion ethernet
    local ethernet_connected=false
    local ethernet_interfaces
    ethernet_interfaces=$(networksetup -listallhardwareports | grep -A 1 Ethernet | grep Device | awk '{print $2}')
    
    for eth_interface in $ethernet_interfaces; do
        local eth_status
        eth_status=$(ifconfig "$eth_interface" 2>/dev/null | grep "status: active")
        if [[ -n "$eth_status" ]]; then
            ethernet_connected=true
            break
        fi
    done
    
    # Appliquer la logique conditionnelle
    local should_enable_wifi=true
    
    # Désactiver le Wi-Fi si ethernet est connecté et la politique l'exige
    if [[ "$ethernet_connected" == "true" && "${DISABLE_WIFI_WITH_ETHERNET:-false}" == "true" ]]; then
        should_enable_wifi=false
        log_action "Wi-Fi désactivé - Connexion Ethernet détectée"
    fi
    
    # Désactiver le Wi-Fi si la batterie est faible et la politique l'exige
    if [[ -n "$battery_level" && "$battery_level" -lt "${MIN_BATTERY_FOR_WIFI:-20}" ]]; then
        should_enable_wifi=false
        log_action "Wi-Fi désactivé - Niveau de batterie faible : $battery_level%"
    fi
    
    # Activer/désactiver le Wi-Fi selon les conditions
    if [[ "$should_enable_wifi" == "true" ]]; then
        networksetup -setairportpower "$interface" on
        log_action "Wi-Fi activé - Conditions remplies"
    else
        networksetup -setairportpower "$interface" off
        log_action "Wi-Fi désactivé - Conditions non remplies"
    fi
}

# Vérification de conformité de sécurité
check_wifi_security_compliance() {
    log_action "Exécution de la vérification de conformité de sécurité Wi-Fi"
    
    local compliance_issues=()
    local wifi_interface
    wifi_interface=$(networksetup -listallhardwareports | grep -A 1 Wi-Fi | grep Device | awk '{print $2}')
    
    if [[ -z "$wifi_interface" ]]; then
        log_action "ERREUR : Aucune interface Wi-Fi trouvée pour la vérification de conformité"
        return 1
    fi
    
    # Vérifier si le Wi-Fi est activé quand il devrait être désactivé
    local power_status
    power_status=$(networksetup -getairportpower "$wifi_interface")
    
    if echo "$power_status" | grep -q "On"; then
        # Wi-Fi activé, vérifier la sécurité du réseau actuel
        local current_network
        current_network=$(networksetup -getairportnetwork "$wifi_interface" | cut -d' ' -f4-)
        
        if [[ "$current_network" != "You are not associated with an AirPort network." ]]; then
            log_action "Connecté au réseau : $current_network"
            
            # Vérifier si le réseau est dans la liste approuvée
            local approved_networks_file="$POLICY_DIR/approved_networks.list"
            if [[ -f "$approved_networks_file" ]]; then
                if ! grep -q "^$current_network$" "$approved_networks_file"; then
                    compliance_issues+=("Connecté à un réseau non approuvé : $current_network")
                fi
            fi
            
            # Vérifier les réseaux ouverts
            if command -v airport >/dev/null 2>&1; then
                local network_security
                network_security=$(airport -I | grep "Security")
                if echo "$network_security" | grep -q "none"; then
                    compliance_issues+=("Connecté à un réseau ouvert/non sécurisé")
                fi
            fi
        fi
    fi
    
    # Générer le rapport de conformité
    if [[ ${#compliance_issues[@]} -eq 0 ]]; then
        log_action "✅ Vérification de conformité de sécurité Wi-Fi réussie"
        return 0
    else
        log_action "❌ Violations de conformité de sécurité Wi-Fi trouvées :"
        for issue in "${compliance_issues[@]}"; do
            log_action "  - $issue"
        done
        return 1
    fi
}

# Fonction de gestion principale
main() {
    local action="${1:-status}"
    local parameter1="$2"
    local parameter2="$3"
    
    setup_directories
    log_action "Contrôle Wi-Fi Roundfleet démarré avec l'action : $action"
    
    case "$action" in
        "disable"|"off")
            turn_off_wifi_basic
            ;;
        "enable"|"on")
            turn_on_wifi "$parameter1"
            ;;
        "status")
            check_wifi_status
            ;;
        "policy")
            enforce_wifi_policy "$parameter1"
            ;;
        "compliance")
            check_wifi_security_compliance
            ;;
        *)
            check_wifi_status
            ;;
    esac
    
    log_action "Contrôle Wi-Fi Roundfleet terminé avec l'action : $action"
}

# Exécuter la fonction principale avec tous les arguments
main "$@"

Modèles de Politiques Wi-Fi

Configuration de Politique Wi-Fi d'Entreprise

# /etc/roundfleet/wifi_policies/corporate_standard.policy
# Politique Wi-Fi d'Entreprise Roundfleet

# Action de politique : disable, enable, scheduled, conditional
WIFI_POLICY_ACTION="conditional"

# Paramètres programmés (pour action scheduled)
WIFI_ENABLE_HOURS="08-18"    # 8h à 18h
WIFI_ENABLE_DAYS="1-5"       # Lundi au vendredi

# Paramètres conditionnels
DISABLE_WIFI_WITH_ETHERNET="true"
MIN_BATTERY_FOR_WIFI="15"

# Paramètres de sécurité
REQUIRE_WPA2_MINIMUM="true"
BLOCK_OPEN_NETWORKS="true"
AUTO_CONNECT_CORPORATE_ONLY="true"

# Gestion de l'alimentation
POWER_OPTIMIZATION_LEVEL="balanced"
AUTO_DISABLE_IDLE="true"
IDLE_TIMEOUT_MINUTES="30"

Politique Wi-Fi Axée Sécurité

# /etc/roundfleet/wifi_policies/high_security.policy
# Politique Wi-Fi Haute Sécurité Roundfleet

WIFI_POLICY_ACTION="conditional"

# Exigences de sécurité
REQUIRE_WPA3_MINIMUM="true"
BLOCK_OPEN_NETWORKS="true"
BLOCK_WEP_NETWORKS="true"
APPROVED_NETWORKS_ONLY="true"

# Désactivation conditionnelle
DISABLE_WIFI_WITH_ETHERNET="true"
DISABLE_WIFI_IN_SECURE_AREAS="true"
MIN_BATTERY_FOR_WIFI="25"

# Surveillance
ENABLE_CONNECTION_LOGGING="true"
ALERT_ON_UNAPPROVED_NETWORKS="true"
SCAN_INTERVAL_MINUTES="5"

Fonctions de Sécurité et Conformité

Gestion de Liste Blanche de Réseaux

#!/bin/bash

# Gérer les réseaux Wi-Fi approuvés
manage_network_whitelist() {
    local action="$1"
    local network_name="$2"
    local whitelist_file="$POLICY_DIR/approved_networks.list"
    
    case "$action" in
        "add")
            if [[ -z "$network_name" ]]; then
                echo "ERREUR : Nom de réseau requis"
                return 1
            fi
            
            # Ajouter le réseau à la liste blanche
            if ! grep -q "^$network_name$" "$whitelist_file" 2>/dev/null; then
                echo "$network_name" >> "$whitelist_file"
                log_action "Réseau ajouté à la liste blanche : $network_name"
            else
                log_action "Réseau déjà dans la liste blanche : $network_name"
            fi
            ;;
        "remove")
            if [[ -z "$network_name" ]]; then
                echo "ERREUR : Nom de réseau requis"
                return 1
            fi
            
            # Supprimer le réseau de la liste blanche
            if [[ -f "$whitelist_file" ]]; then
                grep -v "^$network_name$" "$whitelist_file" > "${whitelist_file}.tmp"
                mv "${whitelist_file}.tmp" "$whitelist_file"
                log_action "Réseau supprimé de la liste blanche : $network_name"
            fi
            ;;
        "list")
            echo "=== Liste Blanche des Réseaux Approuvés ==="
            if [[ -f "$whitelist_file" ]]; then
                cat "$whitelist_file"
            else
                echo "Aucun réseau approuvé configuré"
            fi
            ;;
        *)
            echo "ERREUR : Action de liste blanche invalide : $action"
            return 1
            ;;
    esac
}

# Exemple d'utilisation
# manage_network_whitelist "add" "WiFiEntreprise"
# manage_network_whitelist "list"

Notes Techniques Importantes

Référence des Commandes NetworkSetup

  • networksetup -setairportpower <device> on|off : Activer/désactiver le Wi-Fi
  • networksetup -getairportpower <device> : Vérifier le statut d'alimentation Wi-Fi
  • networksetup -getairportnetwork <device> : Obtenir le réseau Wi-Fi actuel
  • networksetup -listpreferredwirelessnetworks <device> : Lister les réseaux sauvegardés

Considérations de Sécurité

  1. Privilèges Administrateur : Beaucoup de commandes réseau nécessitent un accès admin
  2. Isolation Réseau : Assurer une segmentation réseau appropriée
  3. Gestion des Profils : Auditer et nettoyer régulièrement les profils réseau sauvegardés
  4. Protection Réseau Ouvert : Bloquer les connexions aux réseaux non sécurisés
  5. Surveillance de Conformité : Implémenter une vérification continue de conformité de sécurité

Meilleures Pratiques de Gestion de l'Alimentation

  1. Optimisation Batterie : Désactiver le Wi-Fi quand la batterie est critique
  2. Priorité Ethernet : Préférer les connexions filaires quand disponibles
  3. Contrôle Programmé : Implémenter des politiques Wi-Fi basées sur l'heure
  4. Gestion Inactivité : Désactiver le Wi-Fi pendant les périodes d'inactivité prolongées
  5. Surveillance des Ressources : Suivre les modèles de consommation d'énergie

Cas d'Usage d'Entreprise

  1. Environnements Sécurisés : Liste blanche stricte des réseaux et conformité
  2. Déploiements Économes en Énergie : Optimisation batterie pour travailleurs mobiles
  3. Opérations Programmées : Contrôle Wi-Fi basé sur l'heure pour différentes équipes
  4. Exigences de Conformité : Pistes d'audit et surveillance de sécurité
  5. Standardisation de Flotte : Politiques Wi-Fi cohérentes sur tous les appareils

N'oubliez pas de tester tous les scripts sur des appareils individuels avant de les déployer sur votre environnement Roundfleet, et d'assurer la conformité avec les politiques de sécurité d'entreprise lors de l'implémentation de systèmes de contrôle Wi-Fi d'entreprise.

Contrôle d'Accès aux Sites Web d'Entreprise sur macOS

Contrôlez l'accès aux sites web sur vos appareils Roundfleet en utilisant la gestion avancée du fichier hosts, le filtrage DNS et les contrôles de politique d'entreprise. Ce tutoriel fournit des outils complets pour implémenter les politiques d'accès web organisationnelles.

Comprendre les Méthodes de Contrôle d'Accès aux Sites Web

macOS offre plusieurs approches pour contrôler l'accès aux sites web :

  • Gestion du Fichier Hosts - Redirection DNS locale pour des domaines spécifiques
  • Configuration DNS - Filtrage au niveau réseau via des serveurs DNS personnalisés
  • Paramètres Proxy Système - Routage du trafic via des proxys de filtrage
  • Règles de Pare-feu - Blocage d'adresses IP et de plages de ports spécifiques

Blocage de Sites Web Basique

Bloquer un Site Web Unique

#!/bin/bash

# Bloquer l'accès à un site web spécifique
WEBSITE="www.facebook.com"

# Ajouter une entrée au fichier hosts
echo "127.0.0.1 $WEBSITE" >> /etc/hosts
echo "127.0.0.1 facebook.com" >> /etc/hosts

echo "Accès bloqué à $WEBSITE"

Bloquer Plusieurs Sites Web

#!/bin/bash

# Bloquer plusieurs sites web à la fois
BLOCKED_SITES=(
    "www.facebook.com"
    "facebook.com" 
    "m.facebook.com"
    "www.twitter.com"
    "twitter.com"
    "www.instagram.com"
    "instagram.com"
)

for site in "${BLOCKED_SITES[@]}"; do
    echo "127.0.0.1 $site" >> /etc/hosts
    echo "Bloqué: $site"
done

echo "Blocage de sites web terminé"

Déblocage de Sites Web Basique

Débloquer un Site Web Unique

#!/bin/bash

# Supprimer un site web du fichier hosts
WEBSITE="www.facebook.com"

/usr/bin/sed -i "" "/127.0.0.1 $WEBSITE/d" /etc/hosts
/usr/bin/sed -i "" "/127.0.0.1 facebook.com/d" /etc/hosts

echo "Accès débloqué à $WEBSITE"

Débloquer Tous les Sites Web

#!/bin/bash

# Supprimer toutes les entrées de blocage du fichier hosts
/usr/bin/sed -i "" '/^127.0.0.1.*[^localhost]/d' /etc/hosts

echo "Tous les blocages de sites web supprimés"

Système de Contrôle d'Accès Web d'Entreprise

#!/bin/bash

# Contrôle d'Accès Web d'Entreprise Roundfleet
# Système complet de filtrage web et de gestion de politiques

# Configuration
ROUNDFLEET_DIR="/etc/roundfleet"
POLICIES_DIR="$ROUNDFLEET_DIR/web_policies"
REPORTS_DIR="$ROUNDFLEET_DIR/reports"
COMPLIANCE_DIR="$ROUNDFLEET_DIR/compliance"
AUDIT_DIR="$ROUNDFLEET_DIR/audit"
LOG_FILE="/var/log/roundfleet_web_access.log"
BACKUP_DIR="$ROUNDFLEET_DIR/backups"

# Créer la structure de répertoires
create_directories() {
    local dirs=("$ROUNDFLEET_DIR" "$POLICIES_DIR" "$REPORTS_DIR" "$COMPLIANCE_DIR" "$AUDIT_DIR" "$BACKUP_DIR")
    for dir in "${dirs[@]}"; do
        [[ ! -d "$dir" ]] && mkdir -p "$dir"
    done
}

# Fonction de journalisation
log_action() {
    local message="$1"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo "[$timestamp] $message" | tee -a "$LOG_FILE"
}

# Sauvegarder le fichier hosts
backup_hosts() {
    local backup_file="$BACKUP_DIR/hosts_backup_$(date +%Y%m%d_%H%M%S)"
    cp /etc/hosts "$backup_file"
    log_action "Fichier hosts sauvegardé vers: $backup_file"
}

# Catégories de Sites Web pour le Filtrage d'Entreprise
declare -A WEBSITE_CATEGORIES=(
    ["reseaux_sociaux"]="facebook.com,twitter.com,instagram.com,linkedin.com,snapchat.com,tiktok.com,pinterest.com"
    ["divertissement"]="youtube.com,netflix.com,hulu.com,twitch.tv,spotify.com,reddit.com"
    ["jeux"]="steam.com,epic.com,roblox.com,minecraft.net,ea.com,ubisoft.com"
    ["shopping"]="amazon.com,ebay.com,etsy.com,shopify.com,aliexpress.com"
    ["actualites"]="cnn.com,bbc.com,reuters.com,bloomberg.com,wsj.com"
    ["contenu_adulte"]="example.com"
    ["malveillant"]="malware.com,phishing-site.com,trojan-host.com"
)

# Politiques de Sécurité
declare -A SECURITY_POLICIES=(
    ["securite_elevee"]="reseaux_sociaux,divertissement,jeux,shopping,contenu_adulte,malveillant"
    ["securite_moderee"]="contenu_adulte,malveillant,jeux"
    ["securite_minimale"]="contenu_adulte,malveillant"
    ["equipe_developpement"]="malveillant"
    ["acces_executif"]="malveillant"
)

# Bloquer des sites web par catégorie
block_category() {
    local category="$1"
    local policy="$2"
    
    if [[ -z "${WEBSITE_CATEGORIES[$category]}" ]]; then
        log_action "ERREUR: Catégorie inconnue: $category"
        return 1
    fi
    
    log_action "Blocage de la catégorie: $category (Politique: $policy)"
    
    # Diviser les domaines séparés par des virgules
    IFS=',' read -ra domains <<< "${WEBSITE_CATEGORIES[$category]}"
    
    for domain in "${domains[@]}"; do
        # Ajouter plusieurs variations
        echo "127.0.0.1 $domain" >> /etc/hosts
        echo "127.0.0.1 www.$domain" >> /etc/hosts
        echo "127.0.0.1 m.$domain" >> /etc/hosts
        echo "127.0.0.1 mobile.$domain" >> /etc/hosts
        
        log_action "Domaine bloqué: $domain"
    done
    
    # Sauvegarder les métadonnées de politique
    echo "category=$category,policy=$policy,timestamp=$(date),user=$(whoami)" >> "$POLICIES_DIR/applied_blocks.log"
}

# Appliquer une politique de sécurité
apply_security_policy() {
    local policy="$1"
    
    if [[ -z "${SECURITY_POLICIES[$policy]}" ]]; then
        log_action "ERREUR: Politique de sécurité inconnue: $policy"
        return 1
    fi
    
    log_action "Application de la politique de sécurité: $policy"
    backup_hosts
    
    # Effacer les blocages existants
    /usr/bin/sed -i "" '/^127.0.0.1.*[^localhost]/d' /etc/hosts
    
    # Appliquer les catégories pour cette politique
    IFS=',' read -ra categories <<< "${SECURITY_POLICIES[$policy]}"
    
    for category in "${categories[@]}"; do
        block_category "$category" "$policy"
    done
    
    # Vider le cache DNS
    dscacheutil -flushcache
    killall -HUP mDNSResponder
    
    log_action "Politique de sécurité '$policy' appliquée avec succès"
    
    # Générer un rapport de conformité
    generate_compliance_report "$policy"
}

# Filtrage DNS avancé
configure_dns_filtering() {
    local filter_level="$1"
    
    log_action "Configuration du filtrage DNS: $filter_level"
    
    case "$filter_level" in
        "entreprise")
            # Utiliser des serveurs DNS d'entreprise avec filtrage
            networksetup -setdnsservers "Wi-Fi" 208.67.222.222 208.67.220.220
            networksetup -setdnsservers "Ethernet" 208.67.222.222 208.67.220.220
            ;;
        "securite_familiale")
            # Utiliser un DNS sécurisé pour la famille
            networksetup -setdnsservers "Wi-Fi" 208.67.222.123 208.67.220.123
            networksetup -setdnsservers "Ethernet" 208.67.222.123 208.67.220.123
            ;;
        "securise")
            # Utiliser un DNS axé sur la sécurité
            networksetup -setdnsservers "Wi-Fi" 1.1.1.2 1.0.0.2
            networksetup -setdnsservers "Ethernet" 1.1.1.2 1.0.0.2
            ;;
        "defaut")
            # Réinitialiser au DNS automatique
            networksetup -setdnsservers "Wi-Fi" "Empty"
            networksetup -setdnsservers "Ethernet" "Empty"
            ;;
    esac
    
    log_action "Filtrage DNS configuré: $filter_level"
}

# Gestion de liste blanche pour les sites d'affaires essentiels
manage_whitelist() {
    local action="$1"
    local domain="$2"
    local whitelist_file="$POLICIES_DIR/business_whitelist.txt"
    
    case "$action" in
        "ajouter")
            if ! grep -q "^$domain$" "$whitelist_file" 2>/dev/null; then
                echo "$domain" >> "$whitelist_file"
                # Supprimer du fichier hosts si bloqué
                /usr/bin/sed -i "" "/127.0.0.1.*$domain/d" /etc/hosts
                log_action "Ajouté à la liste blanche: $domain"
            else
                log_action "Domaine déjà en liste blanche: $domain"
            fi
            ;;
        "supprimer")
            if [[ -f "$whitelist_file" ]]; then
                /usr/bin/sed -i "" "/^$domain$/d" "$whitelist_file"
                log_action "Supprimé de la liste blanche: $domain"
            fi
            ;;
        "lister")
            if [[ -f "$whitelist_file" ]]; then
                echo "Liste Blanche d'Affaires:"
                cat "$whitelist_file"
            else
                echo "Aucune liste blanche trouvée"
            fi
            ;;
    esac
}

# Mode d'accès d'urgence
emergency_access() {
    local action="$1"
    local emergency_file="$POLICIES_DIR/emergency_mode.flag"
    
    case "$action" in
        "activer")
            # Sauvegarder les hosts actuels et effacer tous les blocages
            backup_hosts
            cp /etc/hosts "$BACKUP_DIR/hosts_before_emergency"
            /usr/bin/sed -i "" '/^127.0.0.1.*[^localhost]/d' /etc/hosts
            touch "$emergency_file"
            echo "emergency_enabled=$(date)" > "$emergency_file"
            log_action "ACCÈS D'URGENCE ACTIVÉ - Tous les blocages de sites web supprimés"
            ;;
        "desactiver")
            if [[ -f "$emergency_file" ]]; then
                rm "$emergency_file"
                # Restaurer la configuration précédente si disponible
                if [[ -f "$BACKUP_DIR/hosts_before_emergency" ]]; then
                    cp "$BACKUP_DIR/hosts_before_emergency" /etc/hosts
                    log_action "Accès d'urgence désactivé - Configuration précédente restaurée"
                else
                    log_action "Accès d'urgence désactivé - Reconfiguration manuelle requise"
                fi
            else
                log_action "L'accès d'urgence n'est pas actuellement activé"
            fi
            ;;
        "statut")
            if [[ -f "$emergency_file" ]]; then
                echo "Accès d'urgence: ACTIVÉ"
                cat "$emergency_file"
            else
                echo "Accès d'urgence: DÉSACTIVÉ"
            fi
            ;;
    esac
}

# Générer un rapport de conformité complet
generate_compliance_report() {
    local policy="$1"
    local report_file="$REPORTS_DIR/web_access_compliance_$(date +%Y%m%d_%H%M%S).json"
    
    local blocked_domains=$(grep -c "^127.0.0.1" /etc/hosts 2>/dev/null || echo "0")
    local whitelist_count=0
    [[ -f "$POLICIES_DIR/business_whitelist.txt" ]] && whitelist_count=$(wc -l < "$POLICIES_DIR/business_whitelist.txt")
    
    cat > "$report_file" << EOF
{
  "metadonnees_rapport": {
    "horodatage": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
    "nom_hote": "$(hostname)",
    "politique_appliquee": "$policy",
    "version_rapport": "1.0"
  },
  "controle_acces_web": {
    "nombre_domaines_bloques": $blocked_domains,
    "nombre_domaines_liste_blanche": $whitelist_count,
    "filtrage_dns_actif": $(networksetup -getdnsservers Wi-Fi | grep -q "208.67" && echo "true" || echo "false"),
    "mode_urgence": $([ -f "$POLICIES_DIR/emergency_mode.flag" ] && echo "true" || echo "false")
  },
  "politique_securite": {
    "nom": "$policy",
    "categories_bloquees": "$(echo "${SECURITY_POLICIES[$policy]}" | tr ',' ' ')",
    "cadres_conformite": ["SOX", "HIPAA", "NIST", "ISO27001"]
  },
  "statut_systeme": {
    "taille_fichier_hosts": $(wc -l < /etc/hosts),
    "derniere_vidange_dns": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
    "sauvegarde_disponible": $([ -d "$BACKUP_DIR" ] && [ "$(ls -1 "$BACKUP_DIR"/hosts_backup_* 2>/dev/null | wc -l)" -gt 0 ] && echo "true" || echo "false")
  }
}
EOF
    
    log_action "Rapport de conformité généré: $report_file"
    echo "Rapport sauvegardé vers: $report_file"
}

# Vérification de santé et validation
perform_health_check() {
    echo "=== Vérification de Santé du Contrôle d'Accès Web Roundfleet ==="
    
    # Vérifier l'intégrité du fichier hosts
    if [[ -f "/etc/hosts" ]]; then
        echo "✓ Le fichier hosts existe"
        local hosts_size=$(wc -l < /etc/hosts)
        echo "  - Lignes: $hosts_size"
    else
        echo "✗ Fichier hosts manquant"
    fi
    
    # Vérifier les domaines bloqués
    local blocked_count=$(grep -c "^127.0.0.1" /etc/hosts 2>/dev/null || echo "0")
    echo "✓ Domaines bloqués: $blocked_count"
    
    # Vérifier la configuration DNS
    local dns_servers=$(networksetup -getdnsservers Wi-Fi)
    echo "✓ Serveurs DNS: $dns_servers"
    
    # Vérifier la liste blanche
    if [[ -f "$POLICIES_DIR/business_whitelist.txt" ]]; then
        local whitelist_count=$(wc -l < "$POLICIES_DIR/business_whitelist.txt")
        echo "✓ Domaines en liste blanche: $whitelist_count"
    else
        echo "○ Aucune liste blanche configurée"
    fi
    
    # Vérifier le mode d'urgence
    if [[ -f "$POLICIES_DIR/emergency_mode.flag" ]]; then
        echo "⚠️  Mode d'urgence: ACTIF"
    else
        echo "✓ Mode d'urgence: INACTIF"
    fi
    
    # Vérifier l'activité récente
    if [[ -f "$LOG_FILE" ]]; then
        local recent_entries=$(tail -5 "$LOG_FILE" | wc -l)
        echo "✓ Entrées de journal récentes: $recent_entries"
    fi
}

# Fonction de déploiement de flotte
deploy_to_fleet() {
    local policy="$1"
    local fleet_file="$2"
    
    if [[ ! -f "$fleet_file" ]]; then
        log_action "ERREUR: Fichier de flotte non trouvé: $fleet_file"
        return 1
    fi
    
    log_action "Début du déploiement de flotte de la politique: $policy"
    
    while IFS= read -r host; do
        [[ -z "$host" || "$host" =~ ^#.*$ ]] && continue
        
        echo "Déploiement vers: $host"
        
        # Copier ce script vers l'hôte distant et l'exécuter
        ssh "$host" "bash -s" << EOF
#!/bin/bash
# Déploiement distant de la politique d'accès web: $policy

# Créer les répertoires
mkdir -p /etc/roundfleet/{web_policies,reports,compliance,audit,backups}

# Appliquer la politique (simplifié pour l'exécution distante)
$(declare -p WEBSITE_CATEGORIES)
$(declare -p SECURITY_POLICIES)
$(type apply_security_policy | sed '1d')

apply_security_policy "$policy"
EOF
        
        if [[ $? -eq 0 ]]; then
            log_action "Déploiement réussi vers: $host"
        else
            log_action "Échec du déploiement vers: $host"
        fi
        
    done < "$fleet_file"
    
    log_action "Déploiement de flotte terminé"
}

# Fonction d'exécution principale
main() {
    create_directories
    
    case "${1:-}" in
        "appliquer_politique")
            apply_security_policy "$2"
            ;;
        "bloquer_categorie")
            backup_hosts
            block_category "$2" "manuel"
            ;;
        "configurer_dns")
            configure_dns_filtering "$2"
            ;;
        "liste_blanche")
            manage_whitelist "$2" "$3"
            ;;
        "urgence")
            emergency_access "$2"
            ;;
        "verification_sante")
            perform_health_check
            ;;
        "rapport")
            generate_compliance_report "${2:-manuel}"
            ;;
        "deployer")
            deploy_to_fleet "$2" "$3"
            ;;
        "aide"|*)
            echo "Système de Contrôle d'Accès Web Roundfleet"
            echo ""
            echo "Usage: $0 <commande> [options]"
            echo ""
            echo "Commandes:"
            echo "  appliquer_politique <politique>     - Appliquer une politique de sécurité (securite_elevee|securite_moderee|securite_minimale|equipe_developpement|acces_executif)"
            echo "  bloquer_categorie <categorie>       - Bloquer une catégorie de sites web (reseaux_sociaux|divertissement|jeux|shopping|actualites|contenu_adulte|malveillant)"
            echo "  configurer_dns <niveau>             - Configurer le filtrage DNS (entreprise|securite_familiale|securise|defaut)"
            echo "  liste_blanche <action> <domaine>    - Gérer la liste blanche (ajouter|supprimer|lister)"
            echo "  urgence <action>                    - Contrôle d'accès d'urgence (activer|desactiver|statut)"
            echo "  verification_sante                  - Effectuer une vérification de santé du système"
            echo "  rapport [politique]                 - Générer un rapport de conformité"
            echo "  deployer <politique> <fichier_flotte> - Déployer une politique vers la flotte"
            echo ""
            echo "Exemples:"
            echo "  $0 appliquer_politique securite_elevee"
            echo "  $0 liste_blanche ajouter salesforce.com"
            echo "  $0 urgence activer"
            echo "  $0 verification_sante"
            ;;
    esac
}

# Exécuter la fonction principale
main "$@"

## Heures d'Affaires et Contrôles Conviviaux

### Contrôle d'Accès Basé sur l'Heure

```bash
#!/bin/bash

# Appliquer différentes politiques selon les heures d'affaires
apply_time_based_policy() {
    local current_hour=$(date +%H)
    local day_of_week=$(date +%u)
    
    # Heures d'affaires: Lundi-Vendredi 9h - 18h
    if [[ $day_of_week -le 5 ]] && [[ $current_hour -ge 9 ]] && [[ $current_hour -lt 18 ]]; then
        echo "Heures d'affaires détectées - application de la politique stricte"
        apply_security_policy "securite_elevee"
    else
        echo "En dehors des heures d'affaires - application de la politique assouplie"
        apply_security_policy "securite_moderee"
    fi
}

Système de Notification Utilisateur

#!/bin/bash

# Notifier l'utilisateur des changements d'accès aux sites web
notify_user() {
    local message="$1"
    local title="Accès Web Roundfleet"
    
    # Utiliser osascript pour la notification utilisateur
    osascript -e "display notification \"$message\" with title \"$title\" sound name \"Glass\""
    
    # Aussi enregistrer dans le système
    log_action "Notification utilisateur: $message"
}

# Exemple d'utilisation
notify_user "Politique d'accès aux sites web mise à jour en mode Haute Sécurité"

Considérations de Sécurité Importantes

  • Les permissions du fichier hosts doivent être restreintes pour empêcher les modifications non autorisées
  • Le filtrage DNS fournit une protection au niveau réseau au-delà du fichier hosts local
  • Les procédures d'accès d'urgence doivent être documentées et testées
  • Les sauvegardes régulières du fichier hosts et de la configuration sont essentielles
  • La journalisation d'audit aide à suivre les changements de politique et la conformité

Conformité et Rapports

Le système d'entreprise génère des rapports complets pour :

  • Conformité SOX - Contrôles d'accès web des services financiers
  • Exigences HIPAA - Politiques de protection des données de santé
  • Cadre NIST - Alignement sur les normes de cybersécurité
  • ISO 27001 - Gestion de la sécurité de l'information

Tests et Validation

Avant le déploiement en production :

  1. Tester les commandes individuelles sur des systèmes isolés
  2. Vérifier la résolution DNS après application des politiques
  3. Confirmer que les applications d'affaires restent accessibles
  4. Tester les procédures d'urgence et la restauration
  5. Valider la précision des rapports de conformité

Ce système complet transforme le blocage de sites web basique en une plateforme de contrôle d'accès de niveau entreprise avec gestion avancée de politiques, rapports de conformité et capacités de déploiement de flotte.

Gestion des Privilèges Utilisateur et Conformité Sécurité sur macOS

Implémentez une gestion complète des privilèges utilisateur et la conformité sécuritaire sur vos appareils Roundfleet. Ce tutoriel couvre la vérification d'accès administrateur, la surveillance d'escalade de privilèges, le contrôle d'accès basé sur les rôles (RBAC), l'application de politiques de sécurité et les cadres de conformité automatisés pour les environnements d'entreprise.

Comprendre le Système de Privilèges macOS

macOS utilise un système de privilèges en couches pour la sécurité et le contrôle d'accès :

  • Utilisateurs Standard - Accès système de base avec capacités administratives limitées
  • Utilisateurs Administrateur - Accès système complet et capacité de modifier les paramètres système
  • Utilisateur Root - Superutilisateur avec accès système sans restriction (généralement désactivé)
  • Comptes de Service - Comptes système pour exécuter des services et démons
  • Appartenance aux Groupes - Privilèges supplémentaires via les affectations de groupes

Vérification Basique d'Administrateur

Vérifier le Statut Admin d'un Utilisateur Individuel

#!/bin/bash

# Vérifier si un utilisateur spécifique a les privilèges administrateur
check_user_admin_status() {
    local username="$1"
    
    if [[ -z "$username" ]]; then
        echo "❌ Nom d'utilisateur requis"
        return 1
    fi
    
    echo "=== Vérification du Statut Admin pour l'Utilisateur: $username ==="
    
    # Vérifier que l'utilisateur existe
    if ! dscl . -read "/Users/$username" &>/dev/null; then
        echo "❌ L'utilisateur '$username' n'existe pas"
        return 1
    fi
    
    # Vérifier l'appartenance au groupe admin
    if groups "$username" | grep -q -w admin; then
        echo "✅ L'utilisateur '$username' EST un administrateur"
        return 0
    else
        echo "ℹ️  L'utilisateur '$username' n'est PAS un administrateur"
        return 1
    fi
}

# Exemple d'utilisation
# check_user_admin_status "testuser"

Lister Tous les Utilisateurs Administrateur

#!/bin/bash

# Obtenir la liste de tous les utilisateurs administrateur
list_admin_users() {
    echo "=== Liste des Utilisateurs Administrateur ==="
    
    # Obtenir les membres du groupe admin
    local admin_users
    admin_users=$(dscl . -read /Groups/admin GroupMembership 2>/dev/null | cut -d: -f2)
    
    if [[ -z "$admin_users" ]]; then
        echo "⚠️  Aucun utilisateur administrateur trouvé"
        return 1
    fi
    
    echo "Utilisateurs administrateur:"
    for user in $admin_users; do
        # Vérifier que l'utilisateur existe encore et obtenir des informations supplémentaires
        if dscl . -read "/Users/$user" &>/dev/null; then
            local real_name
            real_name=$(dscl . -read "/Users/$user" RealName 2>/dev/null | cut -d: -f2 | xargs)
            local uid
            uid=$(dscl . -read "/Users/$user" UniqueID 2>/dev/null | cut -d: -f2 | xargs)
            
            echo "  👤 $user (UID: $uid) - $real_name"
        else
            echo "  ⚠️  $user (Compte utilisateur non trouvé)"
        fi
    done
    
    return 0
}

# Exécuter la fonction
list_admin_users

Système de Gestion des Privilèges Utilisateur d'Entreprise

#!/bin/bash

# Système de Gestion des Privilèges Utilisateur d'Entreprise Roundfleet
# Contrôle d'accès complet, conformité sécuritaire et surveillance des privilèges

# Configuration
LOG_FILE="/var/log/roundfleet_user_privileges.log"
CONFIG_DIR="/etc/roundfleet/user_management"
POLICIES_DIR="$CONFIG_DIR/policies"
REPORTS_DIR="$CONFIG_DIR/reports"
COMPLIANCE_DIR="$CONFIG_DIR/compliance"
AUDIT_DIR="$CONFIG_DIR/audit"

# Cadres de conformité sécuritaire
declare -A COMPLIANCE_FRAMEWORKS=(
    ["nist"]="least_privilege,separation_duties,access_review,audit_trails"
    ["iso27001"]="access_control,privilege_management,monitoring,documentation"
    ["cis"]="admin_minimization,privilege_escalation_monitoring,account_lifecycle"
    ["sox"]="financial_access_control,privilege_separation,audit_requirements"
    ["hipaa"]="minimum_necessary,access_controls,audit_logs,sanctions"
    ["pci_dss"]="unique_ids,access_control,privilege_limitation,monitoring"
)

# Définitions des rôles utilisateur
declare -A USER_ROLES=(
    ["standard"]="basic_access,file_management,application_usage"
    ["power_user"]="advanced_settings,software_installation,system_preferences"
    ["developer"]="development_tools,system_debugging,certificate_management"
    ["administrator"]="full_system_access,user_management,security_settings"
    ["security_admin"]="security_policies,audit_access,compliance_management"
    ["service_account"]="automated_processes,background_services,api_access"
)

# Modèles d'escalade de privilèges
declare -A ESCALATION_PATTERNS=(
    ["sudo_abuse"]="excessive_sudo_usage,sudo_without_password,sudo_all_commands"
    ["group_manipulation"]="unauthorized_group_addition,privilege_group_access"
    ["file_permissions"]="setuid_modifications,sensitive_file_access,system_file_changes"
    ["service_abuse"]="service_account_usage,daemon_manipulation,system_service_access"
)

# Fonction de journalisation
log_action() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}

# Configuration des répertoires
setup_directories() {
    for dir in "$CONFIG_DIR" "$POLICIES_DIR" "$REPORTS_DIR" "$COMPLIANCE_DIR" "$AUDIT_DIR"; do
        if [[ ! -d "$dir" ]]; then
            mkdir -p "$dir"
            log_action "Répertoire créé: $dir"
        fi
    done
}

# Obtenir des informations complètes sur l'utilisateur
get_user_details() {
    local username="$1"
    
    if [[ -z "$username" ]]; then
        return 1
    fi
    
    # Vérifier si l'utilisateur existe
    if ! dscl . -read "/Users/$username" &>/dev/null; then
        return 1
    fi
    
    local user_info="{}"
    
    # Informations de base sur l'utilisateur
    local uid
    uid=$(dscl . -read "/Users/$username" UniqueID 2>/dev/null | awk '{print $2}')
    local gid
    gid=$(dscl . -read "/Users/$username" PrimaryGroupID 2>/dev/null | awk '{print $2}')
    local real_name
    real_name=$(dscl . -read "/Users/$username" RealName 2>/dev/null | cut -d: -f2- | xargs)
    local home_dir
    home_dir=$(dscl . -read "/Users/$username" NFSHomeDirectory 2>/dev/null | awk '{print $2}')
    local shell
    shell=$(dscl . -read "/Users/$username" UserShell 2>/dev/null | awk '{print $2}')
    
    # Appartenances aux groupes
    local groups_list
    groups_list=$(groups "$username" 2>/dev/null | cut -d: -f2)
    
    # Vérifier le statut admin
    local is_admin="false"
    if groups "$username" | grep -q -w admin; then
        is_admin="true"
    fi
    
    # Informations de dernière connexion
    local last_login
    last_login=$(last -1 "$username" 2>/dev/null | head -1 | awk '{print $4, $5, $6, $7}' || echo "Jamais")
    
    # Permissions du répertoire home
    local home_permissions=""
    if [[ -d "$home_dir" ]]; then
        home_permissions=$(ls -ld "$home_dir" | awk '{print $1}')
    fi
    
    # Informations sur les clés SSH
    local ssh_keys_count=0
    if [[ -d "$home_dir/.ssh" ]]; then
        ssh_keys_count=$(find "$home_dir/.ssh" -name "*.pub" 2>/dev/null | wc -l | xargs)
    fi
    
    user_info=$(cat << EOF
{
    "username": "$username",
    "uid": $uid,
    "gid": $gid,
    "real_name": "$real_name",
    "home_directory": "$home_dir",
    "shell": "$shell",
    "is_administrator": $is_admin,
    "groups": "$(echo $groups_list | sed 's/ /,/g')",
    "last_login": "$last_login",
    "home_permissions": "$home_permissions",
    "ssh_keys_count": $ssh_keys_count
}
EOF
)
    
    echo "$user_info"
}

# Audit complet des privilèges
audit_user_privileges() {
    log_action "Démarrage de l'audit complet des privilèges utilisateur"
    
    local audit_report="$REPORTS_DIR/privilege_audit_$(date '+%Y%m%d_%H%M%S').json"
    
    cat > "$audit_report" << EOF
{
    "audit_metadata": {
        "timestamp": "$(date -Iseconds)",
        "hostname": "$(hostname)",
        "os_version": "$(sw_vers -productVersion)",
        "generator": "Roundfleet User Privilege Manager"
    },
    "system_users": [
EOF

    local first=true
    local total_users=0
    local admin_users=0
    local standard_users=0
    local service_accounts=0
    
    # Obtenir tous les utilisateurs avec UID >= 500 (utilisateurs réguliers) et comptes système
    while IFS= read -r user; do
        local uid
        uid=$(dscl . -read "/Users/$user" UniqueID 2>/dev/null | awk '{print $2}')
        
        if [[ -n "$uid" ]]; then
            total_users=$((total_users + 1))
            
            if [[ "$first" == true ]]; then
                first=false
            else
                echo "," >> "$audit_report"
            fi
            
            local user_details
            user_details=$(get_user_details "$user")
            
            # Catégoriser le type d'utilisateur
            if [[ $uid -lt 500 ]]; then
                service_accounts=$((service_accounts + 1))
            elif echo "$user_details" | jq -r '.is_administrator' | grep -q "true"; then
                admin_users=$((admin_users + 1))
            else
                standard_users=$((standard_users + 1))
            fi
            
            # Ajouter l'évaluation du risque de privilège
            local risk_score
            risk_score=$(assess_privilege_risk "$user")
            
            # Ajouter le statut de conformité sécuritaire
            local compliance_status
            compliance_status=$(assess_user_compliance "$user")
            
            local enhanced_details
            enhanced_details=$(echo "$user_details" | jq ". + {\"privilege_risk_score\": $risk_score, \"compliance_status\": $compliance_status}")
            
            echo "        $enhanced_details" >> "$audit_report"
            
            log_action "Utilisateur audité: $user (UID: $uid)"
        fi
    done < <(dscl . list /Users | grep -v "^_")
    
    cat >> "$audit_report" << EOF
    ],
    "summary": {
        "total_users": $total_users,
        "administrator_users": $admin_users,
        "standard_users": $standard_users,
        "service_accounts": $service_accounts,
        "admin_percentage": $(awk "BEGIN {printf \"%.1f\", ($admin_users/$total_users)*100}")
    },
    "security_recommendations": $(generate_security_recommendations)
}
EOF

    log_action "✅ Audit des privilèges utilisateur terminé: $audit_report"
    echo "$audit_report"
}

# Évaluer le risque de privilège pour un utilisateur
assess_privilege_risk() {
    local username="$1"
    local risk_score=0
    
    # Vérifier si l'utilisateur est admin (risque élevé)
    if groups "$username" | grep -q -w admin; then
        risk_score=$((risk_score + 5))
    fi
    
    # Vérifier les appartenances excessives aux groupes
    local group_count
    group_count=$(groups "$username" | tr ' ' '\n' | wc -l)
    if [[ $group_count -gt 5 ]]; then
        risk_score=$((risk_score + 2))
    fi
    
    # Vérifier les modèles d'utilisation de sudo
    local sudo_entries
    sudo_entries=$(grep "sudo.*$username" /var/log/auth.log 2>/dev/null | wc -l || echo 0)
    if [[ $sudo_entries -gt 50 ]]; then
        risk_score=$((risk_score + 3))
    elif [[ $sudo_entries -gt 10 ]]; then
        risk_score=$((risk_score + 1))
    fi
    
    # Vérifier les clés SSH (mouvement latéral potentiel)
    local home_dir
    home_dir=$(dscl . -read "/Users/$username" NFSHomeDirectory 2>/dev/null | awk '{print $2}')
    if [[ -d "$home_dir/.ssh" ]]; then
        local key_count
        key_count=$(find "$home_dir/.ssh" -name "*.pub" 2>/dev/null | wc -l)
        if [[ $key_count -gt 3 ]]; then
            risk_score=$((risk_score + 2))
        fi
    fi
    
    # Vérifier les modèles de compte de service
    if [[ "$username" =~ ^(service|daemon|app).*$ ]]; then
        risk_score=$((risk_score + 1))
    fi
    
    # Plafonner à 10
    if [[ $risk_score -gt 10 ]]; then
        risk_score=10
    fi
    
    echo "$risk_score"
}

# Évaluer la conformité utilisateur avec les cadres de sécurité
assess_user_compliance() {
    local username="$1"
    
    local compliance_issues=0
    local total_checks=4
    
    # Vérification 1: Principe du moindre privilège
    if groups "$username" | grep -q -w admin; then
        # Les utilisateurs admin ont besoin de justification
        if [[ ! -f "$POLICIES_DIR/admin_justification_$username.conf" ]]; then
            compliance_issues=$((compliance_issues + 1))
        fi
    fi
    
    # Vérification 2: Activité du compte
    local last_login
    last_login=$(last -1 "$username" | head -1 | awk '{print $4}' | grep -v "^$")
    if [[ -z "$last_login" || "$last_login" == "Jamais" ]]; then
        compliance_issues=$((compliance_issues + 1))
    fi
    
    # Vérification 3: Permissions du répertoire home
    local home_dir
    home_dir=$(dscl . -read "/Users/$username" NFSHomeDirectory 2>/dev/null | awk '{print $2}')
    if [[ -d "$home_dir" ]]; then
        local perms
        perms=$(ls -ld "$home_dir" | cut -c1-10)
        if [[ "$perms" =~ ^d.......w.$ ]] || [[ "$perms" =~ ^d........w$ ]]; then
            compliance_issues=$((compliance_issues + 1))
        fi
    fi
    
    # Vérification 4: Conformité à la politique de mot de passe
    local password_policy_compliant="true"
    # Ceci s'intégrerait typiquement avec la vérification de politique de mot de passe
    # Pour la démonstration, nous assumons la conformité
    
    local compliance_score
    compliance_score=$(awk "BEGIN {printf \"%.0f\", (($total_checks - $compliance_issues)/$total_checks)*100}")
    
    local status="conforme"
    if [[ $compliance_score -lt 80 ]]; then
        status="non_conforme"
    elif [[ $compliance_score -lt 90 ]]; then
        status="necessite_attention"
    fi
    
    echo "{\"score\": $compliance_score, \"status\": \"$status\", \"issues\": $compliance_issues}"
}

# Surveiller les tentatives d'escalade de privilèges
monitor_privilege_escalation() {
    log_action "Démarrage de la surveillance d'escalade de privilèges"
    
    local monitoring_report="$AUDIT_DIR/privilege_escalation_$(date '+%Y%m%d_%H%M%S').json"
    
    cat > "$monitoring_report" << EOF
{
    "monitoring_metadata": {
        "timestamp": "$(date -Iseconds)",
        "hostname": "$(hostname)",
        "monitoring_period": "last_24_hours"
    },
    "escalation_events": [
EOF

    local first=true
    local event_count=0
    
    # Surveiller l'utilisation de sudo
    if [[ -f "/var/log/auth.log" ]]; then
        local sudo_events
        sudo_events=$(grep "sudo" /var/log/auth.log | tail -50)
        
        while IFS= read -r line; do
            if [[ -n "$line" ]]; then
                if [[ "$first" == true ]]; then
                    first=false
                else
                    echo "," >> "$monitoring_report"
                fi
                
                local timestamp
                timestamp=$(echo "$line" | awk '{print $1, $2, $3}')
                local user
                user=$(echo "$line" | grep -o "USER=[^ ]*" | cut -d= -f2)
                local command
                command=$(echo "$line" | grep -o "COMMAND=.*" | cut -d= -f2-)
                
                cat >> "$monitoring_report" << EOF
        {
            "type": "sudo_usage",
            "timestamp": "$timestamp",
            "user": "$user",
            "command": "$command",
            "risk_level": "$(assess_command_risk "$command")"
        }
EOF
                event_count=$((event_count + 1))
            fi
        done <<< "$sudo_events"
    fi
    
    # Surveiller les changements d'appartenance aux groupes
    local group_changes
    group_changes=$(grep "group" /var/log/system.log 2>/dev/null | grep -E "(add|remove)" | tail -10)
    
    while IFS= read -r line; do
        if [[ -n "$line" ]]; then
            if [[ "$first" == true ]]; then
                first=false
            else
                echo "," >> "$monitoring_report"
            fi
            
            cat >> "$monitoring_report" << EOF
        {
            "type": "group_change",
            "event": "$line",
            "risk_level": "moyen"
        }
EOF
            event_count=$((event_count + 1))
        fi
    done <<< "$group_changes"
    
    cat >> "$monitoring_report" << EOF
    ],
    "summary": {
        "total_events": $event_count,
        "high_risk_events": $(grep -c '"risk_level": "eleve"' "$monitoring_report" 2>/dev/null || echo 0),
        "medium_risk_events": $(grep -c '"risk_level": "moyen"' "$monitoring_report" 2>/dev/null || echo 0)
    }
}
EOF

    log_action "✅ Surveillance d'escalade de privilèges terminée: $monitoring_report"
    echo "$monitoring_report"
}

# Évaluer le niveau de risque des commandes
assess_command_risk() {
    local command="$1"
    
    # Commandes à haut risque
    if echo "$command" | grep -qE "(rm -rf|chmod 777|chown root|passwd|visudo|su -|sudo su)"; then
        echo "eleve"
    # Commandes à risque moyen
    elif echo "$command" | grep -qE "(install|update|systemctl|launchctl|diskutil)"; then
        echo "moyen"
    # Commandes à faible risque
    else
        echo "faible"
    fi
}

# Appliquer les politiques de sécurité
apply_security_policy() {
    local policy_name="$1"
    local target_users="$2"
    
    log_action "Application de la politique de sécurité: $policy_name"
    
    # Obtenir les utilisateurs cibles
    local users=()
    if [[ -n "$target_users" ]]; then
        IFS=',' read -ra users <<< "$target_users"
    else
        # Appliquer à tous les utilisateurs non-système
        while IFS= read -r user; do
            local uid
            uid=$(dscl . -read "/Users/$user" UniqueID 2>/dev/null | awk '{print $2}')
            if [[ $uid -ge 500 ]]; then
                users+=("$user")
            fi
        done < <(dscl . list /Users | grep -v "^_")
    fi
    
    for user in "${users[@]}"; do
        case "$policy_name" in
            "least_privilege")
                enforce_least_privilege "$user"
                ;;
            "admin_review")
                review_admin_privileges "$user"
                ;;
            "password_policy")
                enforce_password_policy "$user"
                ;;
            "session_limits")
                configure_session_limits "$user"
                ;;
            *)
                log_action "⚠️  Politique inconnue: $policy_name"
                ;;
        esac
    done
    
    log_action "✅ Politique de sécurité '$policy_name' appliquée"
}

# Appliquer le principe du moindre privilège
enforce_least_privilege() {
    local username="$1"
    
    log_action "Application du moindre privilège pour l'utilisateur: $username"
    
    # Vérifier si l'utilisateur a vraiment besoin des privilèges admin
    if groups "$username" | grep -q -w admin; then
        local justification_file="$POLICIES_DIR/admin_justification_$username.conf"
        
        if [[ ! -f "$justification_file" ]]; then
            log_action "⚠️  L'utilisateur admin '$username' manque de documentation de justification"
            
            # Créer un modèle de justification
            cat > "$justification_file" << EOF
# Justification Admin pour l'Utilisateur: $username
# Créé: $(date)
# Statut: EN_ATTENTE_REVISION

JUSTIFICATION_METIER=""
APPROUVE_PAR=""
DATE_APPROBATION=""
DATE_REVISION=""
DATE_REVOCATION=""

# Évaluation des Risques
NIVEAU_PRIVILEGE="admin"
SCORE_JUSTIFICATION=0
REVISION_REQUISE=true

# Notes
COMMENTAIRES=""
EOF
            
            log_action "📝 Modèle de justification créé: $justification_file"
        fi
    fi
}

# Générer des recommandations de sécurité
generate_security_recommendations() {
    local recommendations='['
    local first=true
    
    # Obtenir le nombre d'utilisateurs admin
    local admin_count
    admin_count=$(dscl . -read /Groups/admin GroupMembership 2>/dev/null | wc -w)
    
    if [[ $admin_count -gt 5 ]]; then
        if [[ "$first" == true ]]; then
            first=false
        else
            recommendations+=','
        fi
        recommendations+='"Considérer réduire le nombre de comptes administrateur pour une meilleure sécurité"'
    fi
    
    # Vérifier les comptes inutilisés
    local unused_accounts=0
    while IFS= read -r user; do
        local last_login
        last_login=$(last -1 "$user" | head -1 | awk '{print $4}')
        if [[ -z "$last_login" || "$last_login" == "Jamais" ]]; then
            unused_accounts=$((unused_accounts + 1))
        fi
    done < <(dscl . list /Users | grep -v "^_")
    
    if [[ $unused_accounts -gt 0 ]]; then
        if [[ "$first" == true ]]; then
            first=false
        else
            recommendations+=','
        fi
        recommendations+="\"Considérer désactiver ou supprimer $unused_accounts comptes utilisateur inutilisés\""
    fi
    
    # Ajouter des recommandations par défaut
    if [[ "$first" == true ]]; then
        first=false
    else
        recommendations+=','
    fi
    recommendations+='"Implémenter des cycles de révision de privilèges réguliers"'
    
    recommendations+=','
    recommendations+='"Activer la journalisation d'audit complète"'
    
    recommendations+=','
    recommendations+='"Configurer la surveillance automatisée d\'escalade de privilèges"'
    
    recommendations+=']'
    echo "$recommendations"
}

# Générer un rapport de conformité
generate_compliance_report() {
    local framework="$1"
    
    log_action "Génération du rapport de conformité pour le cadre: $framework"
    
    local compliance_report="$COMPLIANCE_DIR/compliance_${framework}_$(date '+%Y%m%d_%H%M%S').json"
    
    cat > "$compliance_report" << EOF
{
    "compliance_metadata": {
        "timestamp": "$(date -Iseconds)",
        "framework": "$framework",
        "hostname": "$(hostname)",
        "generator": "Roundfleet User Privilege Compliance Manager"
    },
    "framework_requirements": $(get_framework_requirements "$framework"),
    "compliance_assessment": {
        "overall_score": $(calculate_overall_compliance "$framework"),
        "user_compliance": $(assess_all_users_compliance "$framework"),
        "policy_compliance": $(assess_policy_compliance "$framework"),
        "recommendations": $(generate_compliance_recommendations "$framework")
    }
}
EOF

    log_action "✅ Rapport de conformité généré: $compliance_report"
    echo "$compliance_report"
}

# Obtenir les exigences du cadre
get_framework_requirements() {
    local framework="$1"
    
    case "$framework" in
        "nist")
            echo '{"least_privilege": true, "separation_of_duties": true, "access_review": true, "audit_trails": true}'
            ;;
        "iso27001")
            echo '{"access_control": true, "privilege_management": true, "monitoring": true, "documentation": true}'
            ;;
        "cis")
            echo '{"admin_minimization": true, "privilege_escalation_monitoring": true, "account_lifecycle": true}'
            ;;
        *)
            echo '{"basic_access_control": true, "user_management": true}'
            ;;
    esac
}

# Calculer le score de conformité global
calculate_overall_compliance() {
    local framework="$1"
    
    local total_score=0
    local check_count=0
    
    # Vérifications de conformité de base
    check_count=$((check_count + 1))
    local admin_count
    admin_count=$(dscl . -read /Groups/admin GroupMembership 2>/dev/null | wc -w)
    if [[ $admin_count -le 5 ]]; then
        total_score=$((total_score + 20))
    fi
    
    check_count=$((check_count + 1))
    if [[ -f "$LOG_FILE" ]]; then
        total_score=$((total_score + 20))
    fi
    
    check_count=$((check_count + 1))
    if [[ -d "$POLICIES_DIR" ]]; then
        total_score=$((total_score + 20))
    fi
    
    # Vérifications spécifiques au cadre
    case "$framework" in
        "nist")
            check_count=$((check_count + 2))
            # Vérifier la documentation des privilèges
            if find "$POLICIES_DIR" -name "admin_justification_*.conf" | grep -q .; then
                total_score=$((total_score + 20))
            fi
            # Vérifier les capacités d'audit
            if [[ -d "$AUDIT_DIR" ]]; then
                total_score=$((total_score + 20))
            fi
            ;;
    esac
    
    local final_score
    final_score=$(awk "BEGIN {printf \"%.0f\", ($total_score/$check_count)}")
    
    echo "$final_score"
}

# Fonction d'exécution principale
main() {
    local action="${1:-audit}"
    local parameter="$2"
    local additional_param="$3"
    
    log_action "=== Gestion des Privilèges Utilisateur Roundfleet Démarrée ==="
    log_action "Action: $action"
    log_action "Paramètre: ${parameter:-N/A}"
    
    setup_directories
    
    case "$action" in
        "check")
            if [[ -z "$parameter" ]]; then
                echo "Usage: $0 check <nom_utilisateur>"
                exit 1
            fi
            check_user_admin_status "$parameter"
            ;;
        "list")
            list_admin_users
            ;;
        "audit")
            audit_user_privileges
            ;;
        "monitor")
            monitor_privilege_escalation
            ;;
        "policy")
            if [[ -z "$parameter" ]]; then
                echo "Politiques de sécurité disponibles:"
                echo "  - least_privilege"
                echo "  - admin_review"
                echo "  - password_policy"
                echo "  - session_limits"
                echo ""
                echo "Usage: $0 policy <nom_politique> [utilisateurs_cibles]"
                exit 1
            fi
            apply_security_policy "$parameter" "$additional_param"
            ;;
        "compliance")
            if [[ -z "$parameter" ]]; then
                echo "Cadres de conformité disponibles:"
                for framework in "${!COMPLIANCE_FRAMEWORKS[@]}"; do
                    echo "  - $framework: ${COMPLIANCE_FRAMEWORKS[$framework]}"
                done
                echo ""
                echo "Usage: $0 compliance <cadre>"
                exit 1
            fi
            generate_compliance_report "$parameter"
            ;;
        "details")
            if [[ -z "$parameter" ]]; then
                echo "Usage: $0 details <nom_utilisateur>"
                exit 1
            fi
            get_user_details "$parameter" | jq .
            ;;
        *)
            echo "Usage: $0 {check|list|audit|monitor|policy|compliance|details}"
            echo "  check       - Vérifier si un utilisateur spécifique est administrateur"
            echo "  list        - Lister tous les utilisateurs administrateur"
            echo "  audit       - Générer un audit complet des privilèges"
            echo "  monitor     - Surveiller les tentatives d'escalade de privilèges"
            echo "  policy      - Appliquer une politique de sécurité aux utilisateurs"
            echo "  compliance  - Générer un rapport de conformité"
            echo "  details     - Obtenir des informations détaillées sur l'utilisateur"
            exit 1
            ;;
    esac
    
    log_action "=== Gestion des privilèges utilisateur terminée ==="
}

# Exécuter la fonction principale
main "$@"

Fonctionnalités Avancées de Gestion Utilisateur

Contrôle d'Accès Basé sur les Rôles (RBAC)

#!/bin/bash

# Implémenter le système de contrôle d'accès basé sur les rôles
implement_rbac() {
    echo "=== Implémentation du Contrôle d'Accès Basé sur les Rôles ==="
    
    local rbac_config="$CONFIG_DIR/rbac_configuration.json"
    
    cat > "$rbac_config" << EOF
{
    "rbac_configuration": {
        "roles": {
            "utilisateur_standard": {
                "permissions": ["lire_fichiers", "executer_applications", "modifier_preferences_utilisateur"],
                "groups": ["users"],
                "restrictions": ["pas_modifications_systeme", "pas_creation_utilisateur"]
            },
            "utilisateur_avance": {
                "permissions": ["installer_logiciels", "modifier_preferences_systeme", "acces_outils_dev"],
                "groups": ["users", "developer"],
                "restrictions": ["pas_gestion_utilisateur", "pas_parametres_securite"]
            },
            "administrateur": {
                "permissions": ["acces_systeme_complet", "gestion_utilisateur", "configuration_securite"],
                "groups": ["admin", "users"],
                "restrictions": ["audit_requis", "justification_necessaire"]
            },
            "admin_securite": {
                "permissions": ["politiques_securite", "acces_audit", "gestion_conformite"],
                "groups": ["admin", "security"],
                "restrictions": ["approbation_double_requise"]
            }
        },
        "regles_affectation": {
            "affectation_auto": false,
            "approbation_requise": true,
            "periode_revision": "90_jours"
        }
    }
}
EOF

    echo "📋 Configuration RBAC créée: $rbac_config"
}

# Assigner un rôle à l'utilisateur
assign_user_role() {
    local username="$1"
    local role="$2"
    
    if [[ -z "$username" || -z "$role" ]]; then
        echo "Usage: assign_user_role <nom_utilisateur> <role>"
        return 1
    fi
    
    echo "👤 Attribution du rôle '$role' à l'utilisateur '$username'"
    
    # Créer un enregistrement d'attribution de rôle
    local role_file="$POLICIES_DIR/role_assignment_$username.conf"
    
    cat > "$role_file" << EOF
# Attribution de Rôle pour l'Utilisateur: $username
# Attribué: $(date)

ROLE_ATTRIBUE="$role"
ATTRIBUE_PAR="$(whoami)"
DATE_ATTRIBUTION="$(date -Iseconds)"
DATE_REVISION="$(date -d '+90 days' -Iseconds)"
JUSTIFICATION=""

# Permissions du Rôle
$(grep -A 10 "\"$role\":" "$CONFIG_DIR/rbac_configuration.json" 2>/dev/null || echo "# Définition de rôle non trouvée")

# Statut d'Approbation
STATUT_APPROBATION="en_attente"
APPROUVE_PAR=""
DATE_APPROBATION=""
EOF

    log_action "Rôle '$role' attribué à l'utilisateur '$username'"
}

Surveillance Continue de Conformité

#!/bin/bash

# Surveillance continue de conformité
continuous_compliance_monitoring() {
    echo "=== Surveillance Continue de Conformité ==="
    
    local monitoring_config="$CONFIG_DIR/compliance_monitoring.conf"
    
    cat > "$monitoring_config" << EOF
# Configuration de Surveillance de Conformité Roundfleet

# Intervalles de Surveillance
PRIVILEGE_CHECK_INTERVAL=3600    # 1 heure
AUDIT_INTERVAL=86400            # 24 heures
COMPLIANCE_REPORT_INTERVAL=604800  # 1 semaine

# Seuils d'Alerte
MAX_ADMIN_USERS=5
MAX_PRIVILEGE_RISK_SCORE=7
MAX_INACTIVE_DAYS=30

# Cadres de Conformité
ENABLED_FRAMEWORKS="nist,iso27001,cis"

# Paramètres de Notification
ALERT_EMAIL="[email protected]"
SLACK_WEBHOOK_URL=""

# Paramètres de Remédiation
AUTO_REMEDIATION=false
REQUIRE_APPROVAL=true
EOF

    # Créer le script de démon de surveillance
    local daemon_script="/usr/local/bin/roundfleet-compliance-monitor"
    
    cat > "$daemon_script" << 'EOF'
#!/bin/bash

# Démon de Surveillance de Conformité Roundfleet
source /etc/roundfleet/user_management/compliance_monitoring.conf

while true; do
    # Exécuter les vérifications de privilèges
    /usr/local/bin/roundfleet-user-management audit
    
    # Vérifier les violations de conformité
    /usr/local/bin/roundfleet-user-management monitor
    
    # Attendre jusqu'à la prochaine vérification
    sleep $PRIVILEGE_CHECK_INTERVAL
done
EOF

    chmod +x "$daemon_script"
    
    echo "🔄 Surveillance de conformité configurée"
}

Meilleures Pratiques de Sécurité

🔐 Gestion des Privilèges

  • Principe du moindre privilège avec révisions d'accès régulières et exigences de justification
  • Contrôle d'accès basé sur les rôles avec ensembles de permissions prédéfinis et flux d'approbation
  • Surveillance d'escalade de privilèges avec détection en temps réel et alertes
  • Minimisation des comptes administrateur avec justifications documentées pour l'accès admin

📊 Conformité et Audit

  • Support multi-cadres (NIST, ISO 27001, CIS, SOX, HIPAA, PCI DSS)
  • Surveillance continue de conformité avec évaluation et rapports automatisés
  • Pistes d'audit complètes avec journalisation détaillée et capacités forensiques
  • Rapports de conformité réguliers avec scoring de risque et recommandations de remédiation

🛡️ Contrôles de Sécurité

  • Application du contrôle d'accès avec validation d'appartenance aux groupes et surveillance des permissions
  • Gestion de session avec contrôles de timeout et limites de sessions concurrentes
  • Automatisation des politiques de sécurité avec déploiement à l'échelle de la flotte et suivi de conformité
  • Réponse aux incidents avec détection automatisée et capacités de notification

🔧 Opérations d'Entreprise

  • Gestion utilisateur à l'échelle de la flotte avec déploiement centralisé des politiques et surveillance
  • Embarquement/débarquement automatisé avec attribution de rôles et provisioning d'accès
  • Capacités d'intégration avec systèmes existants de gestion d'identité et de sécurité
  • Architecture évolutive supportant des milliers d'appareils et d'utilisateurs

Notes Importantes

  • Privilèges administrateur doivent être accordés avec parcimonie et justification appropriée
  • Révisions d'accès régulières sont essentielles pour maintenir la conformité sécuritaire
  • Configurations de surveillance doivent être adaptées aux exigences de sécurité organisationnelles
  • Cadres de conformité peuvent nécessiter une documentation spécifique et des procédures d'audit
  • Procédures d'accès d'urgence doivent être établies pour l'accès système critique
  • Formation utilisateur sur la gestion des privilèges et les politiques de sécurité améliore la conformité globale

Gestion Entreprise des Détails Utilisateur sur macOS

Récupérez et gérez efficacement les informations utilisateur dans votre déploiement Roundfleet avec un profilage utilisateur de niveau entreprise, des capacités d'audit complètes et des contrôles de sécurité détaillés. Ce tutoriel transforme les commandes dscl de base en solutions robustes de gestion des utilisateurs.

Comprendre la Gestion des Informations Utilisateur en Entreprise

La gestion des détails utilisateur en entreprise nécessite plus que de simples requêtes de service d'annuaire, exigeant :

  • Profilage utilisateur complet avec collecte d'attributs détaillés
  • Classification de sécurité des comptes utilisateur et privilèges
  • Journalisation d'audit pour la surveillance de conformité et sécurité
  • Protection de la vie privée pour les informations utilisateur sensibles
  • Contrôle d'accès basé sur les rôles pour la récupération d'informations
  • Capacités d'intégration avec les services d'annuaire d'entreprise

Opérations d'Information Utilisateur de Base

Commandes de Liste Utilisateur Basiques

# Lister tous les utilisateurs
dscl . list /Users

# Lister les utilisateurs avec UniqueIDs
dscl . list /Users UniqueID

Celles-ci utilisent l'utilitaire en ligne de commande du service d'annuaire (dscl) pour récupérer les informations d'annuaire utilisateur.

Système de Gestion des Détails Utilisateur Entreprise

#!/bin/bash

# Système de Gestion des Détails Utilisateur Entreprise Roundfleet
# Récupération complète d'informations utilisateur avec contrôles entreprise

# Configuration
SCRIPT_NAME="Gestionnaire de Détails Utilisateur Roundfleet"
VERSION="1.0.0"
LOG_FILE="/var/log/roundfleet_user_details.log"
AUDIT_LOG="/var/log/roundfleet_user_audit.log"
REPORT_DIR="/var/reports/roundfleet"
TEMP_DIR="/tmp/roundfleet_users"
PRIVACY_MODE=true
AUDIT_ALL_QUERIES=true
SYSTEM_UID_THRESHOLD=500
PRIVILEGED_GROUPS=("admin" "wheel" "_developer" "staff")
SENSITIVE_ATTRIBUTES=("Password" "ShadowHashData" "JPEGPhoto")

# Créer les répertoires nécessaires
mkdir -p "$TEMP_DIR"
mkdir -p "$REPORT_DIR"
mkdir -p "$(dirname "$LOG_FILE")"
mkdir -p "$(dirname "$AUDIT_LOG")"

# Définir les permissions sécurisées
chmod 700 "$TEMP_DIR"
chmod 750 "$REPORT_DIR"

# Fonctions de journalisation
log_operation() {
    local level="$1"
    local message="$2"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    local username=$(whoami)
    echo "[$timestamp] [$level] [$username] $message" | tee -a "$LOG_FILE"
}

log_audit_query() {
    local query_type="$1"
    local target_user="$2"
    local requested_by="$3"
    local attributes="$4"
    
    if [[ "$AUDIT_ALL_QUERIES" == "true" ]]; then
        local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
        local source_ip=$(who am i | awk '{print $5}' | tr -d '()')
        echo "QUERY|$timestamp|$query_type|$target_user|$requested_by|$source_ip|$attributes" >> "$AUDIT_LOG"
    fi
}

# Obtenir des informations utilisateur complètes
get_user_details() {
    local username="$1"
    local privacy_filter="${2:-true}"
    local requested_by=$(whoami)
    
    log_audit_query "USER_DETAILS" "$username" "$requested_by" "profil_complet"
    
    if ! dscl . -read "/Users/$username" &>/dev/null; then
        log_operation "ERROR" "Utilisateur non trouvé : $username"
        return 1
    fi
    
    echo "=== Détails Utilisateur : $username ==="
    echo "Heure de Requête : $(date)"
    echo "Demandé par : $requested_by"
    echo ""
    
    # Informations de Base
    echo "== Informations de Base =="
    local real_name=$(dscl . -read "/Users/$username" RealName 2>/dev/null | sed 's/RealName: //')
    local uid=$(dscl . -read "/Users/$username" UniqueID 2>/dev/null | awk '{print $2}')
    local gid=$(dscl . -read "/Users/$username" PrimaryGroupID 2>/dev/null | awk '{print $2}')
    local home_dir=$(dscl . -read "/Users/$username" NFSHomeDirectory 2>/dev/null | awk '{print $2}')
    local shell=$(dscl . -read "/Users/$username" UserShell 2>/dev/null | awk '{print $2}')
    
    echo "Nom d'utilisateur : $username"
    echo "Nom Réel : ${real_name:-N/A}"
    echo "ID Utilisateur (UID) : ${uid:-N/A}"
    echo "ID Groupe Principal (GID) : ${gid:-N/A}"
    echo "Répertoire Home : ${home_dir:-N/A}"
    echo "Shell de Connexion : ${shell:-N/A}"
    
    # Classification de Compte
    echo ""
    echo "== Classification de Compte =="
    if [[ $uid -lt $SYSTEM_UID_THRESHOLD ]]; then
        echo "Type de Compte : Compte Système"
        echo "Niveau de Sécurité : Critique"
    else
        echo "Type de Compte : Compte Utilisateur"
        echo "Niveau de Sécurité : Standard"
    fi
    
    # Appartenances aux Groupes
    echo ""
    echo "== Appartenances aux Groupes =="
    local groups=$(groups "$username" 2>/dev/null | cut -d: -f2 | xargs)
    echo "Groupes : ${groups:-Aucun}"
    
    # Vérifier les groupes privilégiés
    echo "Groupes Privilégiés :"
    for group in "${PRIVILEGED_GROUPS[@]}"; do
        if echo "$groups" | grep -q "\b$group\b"; then
            echo "  ✓ $group"
        fi
    done
    
    # État du Compte
    echo ""
    echo "== État du Compte =="
    local account_policy=$(dscl . -read "/Users/$username" accountPolicyData 2>/dev/null)
    if [[ -n "$account_policy" ]]; then
        echo "Politique de Compte : Active"
        echo "$account_policy" | grep -E "(isDisabled|newPasswordRequired|passwordLastSetTime)"
    else
        echo "Politique de Compte : Aucune"
    fi
    
    # Informations de Dernière Connexion
    echo ""
    echo "== Informations de Connexion =="
    local last_login=$(last -1 "$username" 2>/dev/null | head -1)
    if [[ -n "$last_login" && ! "$last_login" =~ "wtmp begins" ]]; then
        echo "Dernière Connexion : $last_login"
    else
        echo "Dernière Connexion : Aucun enregistrement de connexion trouvé"
    fi
    
    # Analyse du Répertoire Home
    echo ""
    echo "== Analyse du Répertoire Home =="
    if [[ -d "$home_dir" ]]; then
        local dir_size=$(du -sh "$home_dir" 2>/dev/null | cut -f1)
        local dir_perms=$(ls -ld "$home_dir" 2>/dev/null | cut -d' ' -f1)
        local dir_owner=$(ls -ld "$home_dir" 2>/dev/null | awk '{print $3":"$4}')
        
        echo "Répertoire Existe : Oui"
        echo "Taille du Répertoire : ${dir_size:-Inconnu}"
        echo "Permissions : ${dir_perms:-Inconnu}"
        echo "Propriétaire : ${dir_owner:-Inconnu}"
    else
        echo "Répertoire Existe : Non"
    fi
    
    # Attributs filtrés pour la vie privée
    if [[ "$privacy_filter" != "true" ]] && [[ "$requested_by" == "root" ]]; then
        echo ""
        echo "== Attributs Étendus (Privilégié) =="
        dscl . -read "/Users/$username" | grep -v -E "$(IFS=\|; echo "${SENSITIVE_ATTRIBUTES[*]}")"
    fi
    
    log_operation "INFO" "Détails utilisateur récupérés pour : $username par $requested_by"
}

# Lister tous les utilisateurs avec classification
list_users_classified() {
    local include_system="${1:-false}"
    local format="${2:-table}"
    local requested_by=$(whoami)
    
    log_audit_query "LIST_USERS" "tous" "$requested_by" "liste_classifiee"
    
    echo "=== Rapport de Classification Utilisateur Roundfleet ==="
    echo "Généré : $(date)"
    echo "Demandé par : $requested_by"
    echo ""
    
    case "$format" in
        "table")
            printf "%-20s %-10s %-15s %-20s %-15s\n" "NOM_UTILISATEUR" "UID" "TYPE" "NOM_REEL" "DERNIERE_CONN"
            printf "%-20s %-10s %-15s %-20s %-15s\n" "---------------" "---" "----" "---------" "-------------"
            ;;
        "csv")
            echo "NOM_UTILISATEUR,UID,TYPE,NOM_REEL,GROUPES,DERNIERE_CONNEXION,HOME_EXISTE"
            ;;
    esac
    
    # Obtenir tous les utilisateurs
    local users=($(dscl . list /Users | grep -v '^_'))
    
    for username in "${users[@]}"; do
        local uid=$(dscl . -read "/Users/$username" UniqueID 2>/dev/null | awk '{print $2}')
        
        # Ignorer les utilisateurs système si non demandé
        if [[ "$include_system" == "false" && $uid -lt $SYSTEM_UID_THRESHOLD ]]; then
            continue
        fi
        
        local real_name=$(dscl . -read "/Users/$username" RealName 2>/dev/null | sed 's/RealName: //' | tr -d '\n')
        local home_dir=$(dscl . -read "/Users/$username" NFSHomeDirectory 2>/dev/null | awk '{print $2}')
        local groups=$(groups "$username" 2>/dev/null | cut -d: -f2 | xargs | tr ' ' ',')
        
        # Déterminer le type de compte
        local account_type
        if [[ $uid -lt $SYSTEM_UID_THRESHOLD ]]; then
            account_type="Système"
        else
            account_type="Utilisateur"
        fi
        
        # Vérifier les privilèges admin
        if echo "$groups" | grep -q "admin"; then
            account_type="${account_type}/Admin"
        fi
        
        # Obtenir la dernière connexion
        local last_login=$(last -1 "$username" 2>/dev/null | head -1 | awk '{print $4" "$5" "$6}')
        if [[ "$last_login" =~ "wtmp begins" ]] || [[ -z "$last_login" ]]; then
            last_login="Jamais"
        fi
        
        # Vérifier l'existence du répertoire home
        local home_exists="Non"
        if [[ -d "$home_dir" ]]; then
            home_exists="Oui"
        fi
        
        # Sortie dans le format demandé
        case "$format" in
            "table")
                printf "%-20s %-10s %-15s %-20s %-15s\n" \
                    "$username" "$uid" "$account_type" "${real_name:0:19}" "${last_login:0:14}"
                ;;
            "csv")
                echo "$username,$uid,$account_type,\"$real_name\",\"$groups\",$last_login,$home_exists"
                ;;
        esac
    done
    
    echo ""
    echo "Total utilisateurs trouvés : ${#users[@]}"
    
    log_operation "INFO" "Liste utilisateur générée par $requested_by (format : $format, inclure_système : $include_system)"
}

# Analyser les privilèges utilisateur et la sécurité
analyze_user_security() {
    local username="$1"
    local requested_by=$(whoami)
    
    log_audit_query "SECURITY_ANALYSIS" "$username" "$requested_by" "audit_privileges"
    
    echo "=== Analyse de Sécurité : $username ==="
    echo "Heure d'Analyse : $(date)"
    echo "Analysé par : $requested_by"
    echo ""
    
    # Validation utilisateur de base
    if ! dscl . -read "/Users/$username" &>/dev/null; then
        log_operation "ERROR" "Utilisateur non trouvé pour l'analyse de sécurité : $username"
        return 1
    fi
    
    local uid=$(dscl . -read "/Users/$username" UniqueID 2>/dev/null | awk '{print $2}')
    local groups=$(groups "$username" 2>/dev/null | cut -d: -f2)
    
    # Évaluation des Risques de Sécurité
    echo "== Évaluation des Risques de Sécurité =="
    local risk_level="FAIBLE"
    local risk_factors=()
    
    # Vérifier les privilèges administratifs
    if echo "$groups" | grep -q "admin"; then
        risk_level="ÉLEVÉ"
        risk_factors+=("Privilèges administratifs")
    fi
    
    # Vérifier l'appartenance au groupe wheel
    if echo "$groups" | grep -q "wheel"; then
        risk_level="CRITIQUE"
        risk_factors+=("Appartenance groupe wheel (accès sudo)")
    fi
    
    # Vérifier l'accès développeur
    if echo "$groups" | grep -q "_developer"; then
        risk_level="MOYEN"
        risk_factors+=("Appartenance groupe développeur")
    fi
    
    # Vérifier compte système
    if [[ $uid -lt $SYSTEM_UID_THRESHOLD ]]; then
        risk_level="CRITIQUE"
        risk_factors+=("Compte système (UID < $SYSTEM_UID_THRESHOLD)")
    fi
    
    echo "Niveau de Risque : $risk_level"
    echo "Facteurs de Risque :"
    for factor in "${risk_factors[@]}"; do
        echo "  - $factor"
    done
    
    # Analyse des Privilèges
    echo ""
    echo "== Analyse des Privilèges =="
    echo "Appartenances aux Groupes :"
    for group in $groups; do
        local group_info=""
        case "$group" in
            "admin") group_info="Accès administratif" ;;
            "wheel") group_info="Privilèges sudo" ;;
            "_developer") group_info="Accès outils développeur" ;;
            "staff") group_info="Groupe utilisateur standard" ;;
            *) group_info="Groupe standard" ;;
        esac
        echo "  $group - $group_info"
    done
    
    # Vérification accès sudo
    echo ""
    echo "== Vérification Accès Sudo =="
    if sudo -l -U "$username" &>/dev/null; then
        echo "Accès Sudo : ACCORDÉ"
        echo "Règles Sudo :"
        sudo -l -U "$username" 2>/dev/null | grep -v "may run"
    else
        echo "Accès Sudo : REFUSÉ"
    fi
    
    # Vérification activité récente
    echo ""
    echo "== Activité Récente =="
    echo "Connexions Récentes :"
    last "$username" | head -5
    
    log_operation "INFO" "Analyse de sécurité terminée pour l'utilisateur : $username (Risque : $risk_level)"
}

# Générer un rapport d'audit utilisateur complet
generate_user_audit_report() {
    local report_type="${1:-resume}"
    local output_format="${2:-text}"
    local requested_by=$(whoami)
    
    local report_file="$REPORT_DIR/user_audit_$(date +%Y%m%d_%H%M%S).$output_format"
    
    log_audit_query "AUDIT_REPORT" "tous" "$requested_by" "audit_complet"
    
    {
        echo "Rapport d'Audit Utilisateur Roundfleet"
        echo "===================================="
        echo "Type de Rapport : $report_type"
        echo "Généré : $(date)"
        echo "Généré par : $requested_by"
        echo "Nom d'hôte : $(hostname)"
        echo ""
        
        case "$report_type" in
            "resume")
                echo "== Résumé Utilisateur =="
                local total_users=$(dscl . list /Users | grep -v '^_' | wc -l)
                local system_users=$(dscl . list /Users UniqueID | awk '$2 < '$SYSTEM_UID_THRESHOLD' {count++} END {print count+0}')
                local regular_users=$((total_users - system_users))
                local admin_users=$(dseditgroup -o checkmember -m admin 2>/dev/null | wc -l)
                
                echo "Total Utilisateurs : $total_users"
                echo "Comptes Système : $system_users"
                echo "Utilisateurs Réguliers : $regular_users"
                echo "Utilisateurs Administratifs : $admin_users"
                ;;
            "detaille")
                echo "== Analyse Détaillée des Utilisateurs =="
                list_users_classified "true" "table"
                ;;
            "securite")
                echo "== Évaluation de Sécurité =="
                echo "Utilisateurs à Privilèges Élevés :"
                for user in $(dscl . list /Users); do
                    if [[ ! "$user" =~ ^_ ]]; then
                        local groups=$(groups "$user" 2>/dev/null | cut -d: -f2)
                        if echo "$groups" | grep -q -E "(admin|wheel|_developer)"; then
                            echo "  $user : $groups"
                        fi
                    fi
                done
                ;;
        esac
        
        echo ""
        echo "== Activité d'Audit Récente =="
        if [[ -f "$AUDIT_LOG" ]]; then
            echo "Requêtes récentes (10 dernières) :"
            tail -10 "$AUDIT_LOG"
        else
            echo "Aucun log d'audit disponible"
        fi
        
        echo ""
        echo "== Notes de Conformité =="
        echo "- Toutes les requêtes utilisateur sont enregistrées à des fins d'audit"
        echo "- Les attributs sensibles sont protégés par des filtres de confidentialité"
        echo "- L'accès administratif est suivi et surveillé"
        echo "- Rapport généré en conformité avec les politiques de sécurité d'entreprise"
        
    } > "$report_file"
    
    echo "Rapport d'audit utilisateur généré : $report_file"
    log_operation "INFO" "Rapport d'audit utilisateur généré par $requested_by : $report_file"
}

# Trouver les utilisateurs par critères
find_users_by_criteria() {
    local criteria="$1"
    local value="$2"
    local requested_by=$(whoami)
    
    log_audit_query "SEARCH_USERS" "$criteria:$value" "$requested_by" "recherche_criteres"
    
    echo "=== Résultats de Recherche Utilisateur ==="
    echo "Critères : $criteria"
    echo "Valeur : $value"
    echo "Heure de Recherche : $(date)"
    echo ""
    
    local found_users=()
    
    case "$criteria" in
        "uid")
            local users=($(dscl . list /Users UniqueID | awk -v val="$value" '$2 == val {print $1}'))
            found_users=("${users[@]}")
            ;;
        "gid")
            local users=($(dscl . list /Users PrimaryGroupID | awk -v val="$value" '$2 == val {print $1}'))
            found_users=("${users[@]}")
            ;;
        "group")
            local group_members=$(dseditgroup -o checkmember -m "$value" 2>/dev/null)
            if [[ $? -eq 0 ]]; then
                found_users=("$value")
            fi
            ;;
        "shell")
            local users=($(dscl . list /Users UserShell | grep "$value" | awk '{print $1}'))
            found_users=("${users[@]}")
            ;;
        "home")
            local users=($(dscl . list /Users NFSHomeDirectory | grep "$value" | awk '{print $1}'))
            found_users=("${users[@]}")
            ;;
        *)
            echo "Erreur : Critères de recherche inconnus '$criteria'"
            echo "Critères supportés : uid, gid, group, shell, home"
            return 1
            ;;
    esac
    
    if [[ ${#found_users[@]} -eq 0 ]]; then
        echo "Aucun utilisateur trouvé correspondant aux critères"
    else
        echo "Trouvé ${#found_users[@]} utilisateur(s) :"
        for user in "${found_users[@]}"; do
            echo "  $user"
        done
    fi
    
    log_operation "INFO" "Recherche utilisateur terminée : $criteria=$value, trouvé ${#found_users[@]} utilisateurs"
}

# Fonction principale de gestion des détails utilisateur
main() {
    local action="${1:-help}"
    
    case "$action" in
        "list")
            local include_system="${2:-false}"
            local format="${3:-table}"
            
            list_users_classified "$include_system" "$format"
            ;;
        "details")
            local username="$2"
            local privacy_filter="${3:-true}"
            
            if [[ -z "$username" ]]; then
                echo "Usage : $0 details <nom_utilisateur> [filtre_confidentialite]"
                exit 1
            fi
            
            get_user_details "$username" "$privacy_filter"
            ;;
        "security")
            local username="$2"
            
            if [[ -z "$username" ]]; then
                echo "Usage : $0 security <nom_utilisateur>"
                exit 1
            fi
            
            analyze_user_security "$username"
            ;;
        "search")
            local criteria="$2"
            local value="$3"
            
            if [[ -z "$criteria" || -z "$value" ]]; then
                echo "Usage : $0 search <criteres> <valeur>"
                echo "Critères : uid, gid, group, shell, home"
                exit 1
            fi
            
            find_users_by_criteria "$criteria" "$value"
            ;;
        "report")
            local report_type="${2:-resume}"
            local output_format="${3:-text}"
            
            generate_user_audit_report "$report_type" "$output_format"
            ;;
        "help"|*)
            echo "$SCRIPT_NAME v$VERSION"
            echo "Gestion Entreprise des Détails Utilisateur"
            echo ""
            echo "Usage : $0 <action> [options]"
            echo ""
            echo "Actions :"
            echo "  list [inclure_système] [format]             - Lister tous les utilisateurs avec classification"
            echo "  details <nom_utilisateur> [filtre_confid]   - Obtenir des détails utilisateur complets"
            echo "  security <nom_utilisateur>                  - Analyser la sécurité et privilèges utilisateur"
            echo "  search <critères> <valeur>                  - Trouver les utilisateurs par critères spécifiques"
            echo "  report [type] [format]                      - Générer des rapports d'audit utilisateur"
            echo "  help                                         - Afficher ce message d'aide"
            echo ""
            echo "Options :"
            echo "  inclure_système : true/false (défaut : false)"
            echo "  format : table/csv (défaut : table)"
            echo "  filtre_confid : true/false (défaut : true)"
            echo "  critères : uid, gid, group, shell, home"
            echo "  type : resume, detaille, securite (défaut : resume)"
            echo ""
            echo "Fonctionnalités :"
            echo "  • Récupération complète d'informations utilisateur"
            echo "  • Évaluation des risques de sécurité et analyse des privilèges"
            echo "  • Gestion des attributs sensibles protégée par confidentialité"
            echo "  • Journalisation d'audit détaillée pour la conformité"
            echo "  • Formats de sortie multiples (table, CSV)"
            echo "  • Capacités de recherche et filtrage avancées"
            echo "  • Rapports et analyses de niveau entreprise"
            ;;
    esac
}

# Exécuter la fonction principale avec tous les arguments
main "$@"

Commandes de Référence Rapide

Opérations de Liste Utilisateur

# Lister tous les utilisateurs réguliers (excluant les comptes système)
./user_manager.sh list

# Lister tous les utilisateurs incluant les comptes système
./user_manager.sh list true

# Lister les utilisateurs en format CSV
./user_manager.sh list false csv

# Lister tous les utilisateurs avec comptes système en CSV
./user_manager.sh list true csv

Récupération de Détails Utilisateur

# Obtenir les détails utilisateur standard
./user_manager.sh details jean.dupont

# Obtenir des informations utilisateur détaillées (admin uniquement)
./user_manager.sh details jean.dupont false

# Obtenir les détails utilisateur avec filtrage de confidentialité
./user_manager.sh details admin.utilisateur true

Analyse de Sécurité

# Analyser la sécurité et privilèges utilisateur
./user_manager.sh security jean.dupont

# Analyse de sécurité pour utilisateur admin
./user_manager.sh security admin.utilisateur

# Analyser la sécurité du compte système
./user_manager.sh security root

Opérations de Recherche Utilisateur

# Trouver les utilisateurs par UID
./user_manager.sh search uid 501

# Trouver les utilisateurs par appartenance au groupe
./user_manager.sh search group admin

# Trouver les utilisateurs par shell
./user_manager.sh search shell "/bin/zsh"

# Trouver les utilisateurs par motif de répertoire home
./user_manager.sh search home "/Users"

Opérations de Rapport

# Générer un rapport d'audit résumé
./user_manager.sh report

# Générer un rapport utilisateur détaillé
./user_manager.sh report detaille

# Générer un rapport axé sur la sécurité
./user_manager.sh report securite

# Générer un rapport CSV
./user_manager.sh report resume csv

Exemples d'Intégration

Intégration JAMF Pro

#!/bin/bash

# Script JAMF Pro pour gestion des détails utilisateur entreprise
# Paramètres : $4 = action, $5 = nom_utilisateur, $6 = options

ACTION="$4"
NOM_UTILISATEUR="$5"
OPTIONS="$6"

# Télécharger le gestionnaire utilisateur s'il n'est pas présent
if [[ ! -f "/usr/local/bin/roundfleet_user_manager.sh" ]]; then
    curl -o "/usr/local/bin/roundfleet_user_manager.sh" "https://scripts.roundfleet.com/user_manager.sh"
    chmod +x "/usr/local/bin/roundfleet_user_manager.sh"
fi

# Exécuter l'opération de gestion utilisateur
case "$ACTION" in
    "audit")
        /usr/local/bin/roundfleet_user_manager.sh report detaille text
        ;;
    "security")
        /usr/local/bin/roundfleet_user_manager.sh security "$NOM_UTILISATEUR"
        ;;
    "list")
        /usr/local/bin/roundfleet_user_manager.sh list true csv
        ;;
    *)
        echo "Action invalide : $ACTION"
        exit 1
        ;;
esac

exit $?

Fonctionnalités de Conformité et Confidentialité

Protection de la Confidentialité

# Gestion des informations utilisateur conforme à la confidentialité
get_privacy_compliant_details() {
    local username="$1"
    local requester="$2"
    local purpose="$3"
    
    # Enregistrer l'accès sensible à la confidentialité
    echo "PRIVACY_ACCESS|$(date)|$username|$requester|$purpose" >> "/var/log/privacy_access.log"
    
    # Filtrer les attributs sensibles selon les permissions du demandeur
    if [[ "$requester" != "root" ]]; then
        # Supprimer les champs sensibles pour les utilisateurs non-root
        dscl . -read "/Users/$username" | grep -v -E "(Password|ShadowHashData|JPEGPhoto)"
    else
        # Accès complet pour root avec journalisation d'audit
        dscl . -read "/Users/$username"
    fi
}

Conformité RGPD

# Export de données utilisateur conforme RGPD
export_user_data_gdpr() {
    local username="$1"
    local export_file="/tmp/user_export_${username}_$(date +%s).json"
    
    # Enregistrer la demande d'export de données
    log_operation "RGPD_EXPORT" "Export de données demandé pour l'utilisateur : $username"
    
    # Créer un export JSON structuré
    {
        echo "{"
        echo "  \"export_timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\","
        echo "  \"username\": \"$username\","
        echo "  \"personal_data\": {"
        
        # Inclure uniquement les données personnelles pertinentes au RGPD
        local real_name=$(dscl . -read "/Users/$username" RealName 2>/dev/null | sed 's/RealName: //')
        echo "    \"real_name\": \"$real_name\","
        echo "    \"home_directory\": \"$(dscl . -read "/Users/$username" NFSHomeDirectory | awk '{print $2}')\","
        echo "    \"creation_date\": \"$(stat -f %SB /Users/$username 2>/dev/null)\""
        
        echo "  },"
        echo "  \"compliance_note\": \"Cet export contient des données personnelles telles que définies par l'Article 4(1) du RGPD\""
        echo "}"
    } > "$export_file"
    
    echo "Export de données RGPD créé : $export_file"
}

Meilleures Pratiques

  1. Implémenter un accès basé sur les rôles pour la récupération d'informations utilisateur
  2. Activer la journalisation d'audit complète pour toutes les requêtes utilisateur
  3. Utiliser des filtres de confidentialité pour protéger les attributs utilisateur sensibles
  4. Évaluations de sécurité régulières des comptes à privilèges élevés
  5. Intégrer avec les services d'annuaire d'entreprise pour une gestion centralisée
  6. Surveiller les modèles d'activité utilisateur inhabituels
  7. Générer des rapports de conformité réguliers à des fins d'audit
  8. Protéger les données utilisateur sensibles selon les réglementations de confidentialité

Ce système de gestion des détails utilisateur entreprise fournit une récupération complète d'informations utilisateur, une analyse de sécurité et des capacités d'audit tout en maintenant la protection de la confidentialité et les standards de conformité pour une gestion efficace des utilisateurs Roundfleet.

Gestion Entreprise de Création Utilisateur sur macOS

Créez et provisionnez efficacement les comptes utilisateur dans votre déploiement Roundfleet avec une gestion du cycle de vie utilisateur de niveau entreprise, des workflows automatisés et des contrôles de sécurité complets. Ce tutoriel transforme les commandes dscl et sysadminctl de base en solutions robustes de provisioning utilisateur.

Comprendre la Gestion de Création Utilisateur en Entreprise

La création utilisateur en entreprise nécessite plus qu'un simple provisioning de comptes, exigeant :

  • Workflows de provisioning automatisés avec configuration basée sur des modèles
  • Création de comptes axée sécurité avec attribution appropriée des privilèges
  • Intégration standardisée d'utilisateurs avec structures d'annuaire cohérentes
  • Capacités d'intégration avec les systèmes d'identité d'entreprise
  • Journalisation d'audit pour la surveillance de conformité et sécurité
  • Opérations utilisateur en masse pour une gestion de flotte efficace

Opérations de Création Utilisateur de Base

Commandes de Création Utilisateur Basiques

# Création utilisateur basée sur dscl
sudo dscl . -create /Users/Username
sudo dscl . -create /Users/Username RealName "John Doe"
sudo dscl . -passwd /Users/Username password_here
sudo dscl . -create /Users/Username UniqueID 1088
sudo dscl . -create /Users/Username PrimaryGroupID 20
sudo dscl . -create /Users/Username UserShell /bin/bash
sudo dscl . -create /Users/Username NFSHomeDirectory /Users/Username

# Création utilisateur basée sur sysadminctl
sysadminctl -addUser <username> -password <password>

Celles-ci utilisent l'utilitaire en ligne de commande du service d'annuaire (dscl) et le contrôle administrateur système (sysadminctl) pour la gestion des comptes utilisateur.

Système de Gestion de Création Utilisateur Entreprise

#!/bin/bash

# Système de Gestion de Création Utilisateur Entreprise Roundfleet
# Provisioning utilisateur complet avec contrôles entreprise et automatisation

# Configuration
SCRIPT_NAME="Gestionnaire de Création Utilisateur Roundfleet"
VERSION="1.0.0"
LOG_FILE="/var/log/roundfleet_user_creation.log"
AUDIT_LOG="/var/log/roundfleet_user_audit.log"
TEMPLATES_DIR="/etc/roundfleet/user_templates"
PROVISIONING_DIR="/var/lib/roundfleet/provisioning"
TEMP_DIR="/tmp/roundfleet_users"
MIN_UID=1000
MAX_UID=65000
DEFAULT_SHELL="/bin/zsh"
HOME_BASE_DIR="/Users"
COMPANY_DOMAIN="company.local"
REQUIRE_SECURE_PASSWORDS=true
ENFORCE_NAMING_CONVENTION=true
AUTO_FILEVAULT_ENABLE=true
STANDARD_GROUPS=("staff" "_appserverusr" "_appserveradm")
ADMIN_GROUPS=("admin" "staff" "_developer")
DEVELOPER_GROUPS=("staff" "_developer" "_appserverusr")

# Créer les répertoires nécessaires
mkdir -p "$TEMPLATES_DIR"
mkdir -p "$PROVISIONING_DIR"
mkdir -p "$TEMP_DIR"
mkdir -p "$(dirname "$LOG_FILE")"
mkdir -p "$(dirname "$AUDIT_LOG")"

# Définir les permissions sécurisées
chmod 700 "$TEMP_DIR"
chmod 750 "$PROVISIONING_DIR"
chmod 755 "$TEMPLATES_DIR"

# Fonctions de journalisation
log_operation() {
    local level="$1"
    local message="$2"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    local admin_user=$(whoami)
    echo "[$timestamp] [$level] [$admin_user] $message" | tee -a "$LOG_FILE"
}

log_audit_action() {
    local action_type="$1"
    local target_user="$2"
    local performed_by="$3"
    local details="$4"
    
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    local source_ip=$(who am i | awk '{print $5}' | tr -d '()')
    echo "ACTION|$timestamp|$action_type|$target_user|$performed_by|$source_ip|$details" >> "$AUDIT_LOG"
}

# Générer un mot de passe sécurisé aléatoire
generate_secure_password() {
    local length="${1:-12}"
    local complexity="${2:-high}"
    
    case "$complexity" in
        "high")
            # Haute complexité : majuscules, minuscules, chiffres, symboles
            openssl rand -base64 32 | tr -d "=+/" | cut -c1-${length}
            ;;
        "medium")
            # Complexité moyenne : majuscules, minuscules, chiffres
            LC_ALL=C tr -dc 'A-Za-z0-9' </dev/urandom | head -c ${length}
            ;;
        "basic")
            # Complexité basique : minuscules et chiffres
            LC_ALL=C tr -dc 'a-z0-9' </dev/urandom | head -c ${length}
            ;;
        *)
            echo "Erreur : Niveau de complexité inconnu"
            return 1
            ;;
    esac
}

# Valider la politique de mot de passe
validate_password() {
    local password="$1"
    local min_length=8
    local errors=()
    
    # Vérifier la longueur minimale
    if [[ ${#password} -lt $min_length ]]; then
        errors+=("Le mot de passe doit contenir au moins $min_length caractères")
    fi
    
    # Vérifier la lettre majuscule
    if [[ ! "$password" =~ [A-Z] ]]; then
        errors+=("Le mot de passe doit contenir au moins une lettre majuscule")
    fi
    
    # Vérifier la lettre minuscule
    if [[ ! "$password" =~ [a-z] ]]; then
        errors+=("Le mot de passe doit contenir au moins une lettre minuscule")
    fi
    
    # Vérifier le chiffre
    if [[ ! "$password" =~ [0-9] ]]; then
        errors+=("Le mot de passe doit contenir au moins un chiffre")
    fi
    
    # Vérifier le caractère spécial
    if [[ ! "$password" =~ [^A-Za-z0-9] ]]; then
        errors+=("Le mot de passe doit contenir au moins un caractère spécial")
    fi
    
    if [[ ${#errors[@]} -gt 0 ]]; then
        echo "Validation du mot de passe échouée :"
        printf '  - %s\n' "${errors[@]}"
        return 1
    fi
    
    return 0
}

# Valider le nom d'utilisateur selon la convention de nommage entreprise
validate_username() {
    local username="$1"
    local errors=()
    
    # Vérifier la longueur (3-20 caractères)
    if [[ ${#username} -lt 3 || ${#username} -gt 20 ]]; then
        errors+=("Le nom d'utilisateur doit contenir 3-20 caractères")
    fi
    
    # Vérifier les caractères valides (alphanumériques, points, tirets, underscores)
    if [[ ! "$username" =~ ^[a-zA-Z0-9._-]+$ ]]; then
        errors+=("Le nom d'utilisateur ne peut contenir que des lettres, chiffres, points, tirets et underscores")
    fi
    
    # Vérifier qu'il commence par une lettre
    if [[ ! "$username" =~ ^[a-zA-Z] ]]; then
        errors+=("Le nom d'utilisateur doit commencer par une lettre")
    fi
    
    # Vérifier les noms réservés
    local reserved_names=("admin" "root" "daemon" "nobody" "wheel" "operator" "system")
    for reserved in "${reserved_names[@]}"; do
        if [[ "$username" == "$reserved" ]]; then
            errors+=("Le nom d'utilisateur '$username' est réservé")
        fi
    done
    
    # Vérifier si le nom d'utilisateur existe déjà
    if dscl . -read "/Users/$username" &>/dev/null; then
        errors+=("Le nom d'utilisateur '$username' existe déjà")
    fi
    
    if [[ ${#errors[@]} -gt 0 ]]; then
        echo "Validation du nom d'utilisateur échouée :"
        printf '  - %s\n' "${errors[@]}"
        return 1
    fi
    
    return 0
}

# Trouver le prochain UID disponible
find_next_uid() {
    local start_uid="${1:-$MIN_UID}"
    local max_uid="${2:-$MAX_UID}"
    
    # Obtenir tous les UIDs existants
    local existing_uids=($(dscl . list /Users UniqueID | awk '{print $2}' | sort -n))
    
    # Trouver le premier UID disponible
    for ((uid=start_uid; uid<=max_uid; uid++)); do
        local uid_exists=false
        for existing_uid in "${existing_uids[@]}"; do
            if [[ $uid -eq $existing_uid ]]; then
                uid_exists=true
                break
            fi
        done
        
        if [[ "$uid_exists" == "false" ]]; then
            echo "$uid"
            return 0
        fi
    done
    
    echo "Erreur : Aucun UID disponible trouvé dans la plage $start_uid-$max_uid"
    return 1
}

# Créer un compte utilisateur avec paramètres entreprise
create_enterprise_user() {
    local username="$1"
    local real_name="$2"
    local password="$3"
    local user_type="${4:-standard}"
    local department="${5:-General}"
    local admin_user=$(whoami)
    
    log_audit_action "USER_CREATION_START" "$username" "$admin_user" "type=$user_type,department=$department"
    
    # Valider les entrées
    if ! validate_username "$username"; then
        log_operation "ERROR" "Validation du nom d'utilisateur échouée pour : $username"
        return 1
    fi
    
    if [[ "$REQUIRE_SECURE_PASSWORDS" == "true" ]] && ! validate_password "$password"; then
        log_operation "ERROR" "Validation du mot de passe échouée pour l'utilisateur : $username"
        return 1
    fi
    
    # Trouver l'UID disponible
    local uid
    uid=$(find_next_uid)
    if [[ $? -ne 0 ]]; then
        log_operation "ERROR" "Échec de trouver un UID disponible pour : $username"
        return 1
    fi
    
    echo "=== Création Utilisateur Entreprise : $username ==="
    echo "Nom Réel : $real_name"
    echo "Type Utilisateur : $user_type"
    echo "Département : $department"
    echo "UID Assigné : $uid"
    echo "Administrateur : $admin_user"
    echo ""
    
    # Créer le compte utilisateur avec dscl
    echo "Création du compte utilisateur..."
    
    # Création utilisateur de base
    if ! sudo dscl . -create "/Users/$username"; then
        log_operation "ERROR" "Échec de créer l'utilisateur : $username"
        return 1
    fi
    
    # Définir le nom réel
    sudo dscl . -create "/Users/$username" RealName "$real_name"
    
    # Définir le mot de passe
    sudo dscl . -passwd "/Users/$username" "$password"
    
    # Définir l'UID
    sudo dscl . -create "/Users/$username" UniqueID "$uid"
    
    # Déterminer l'ID du groupe principal selon le type d'utilisateur
    local primary_gid
    case "$user_type" in
        "admin")
            primary_gid=80  # groupe admin
            ;;
        "developer")
            primary_gid=20  # groupe staff
            ;;
        "standard"|*)
            primary_gid=20  # groupe staff
            ;;
    esac
    
    sudo dscl . -create "/Users/$username" PrimaryGroupID "$primary_gid"
    
    # Définir le shell
    sudo dscl . -create "/Users/$username" UserShell "$DEFAULT_SHELL"
    
    # Créer le répertoire home
    local home_dir="$HOME_BASE_DIR/$username"
    sudo dscl . -create "/Users/$username" NFSHomeDirectory "$home_dir"
    
    # Ajouter les attributs entreprise
    sudo dscl . -create "/Users/$username" Department "$department"
    sudo dscl . -create "/Users/$username" Company "$(hostname -s | cut -d. -f1)"
    sudo dscl . -create "/Users/$username" CreationDate "$(date)"
    sudo dscl . -create "/Users/$username" CreatedBy "$admin_user"
    
    # Ajouter l'indice de mot de passe
    sudo dscl . -create "/Users/$username" hint "Contactez le support IT pour l'assistance mot de passe"
    
    # Configurer les appartenances aux groupes selon le type d'utilisateur
    echo "Configuration des appartenances aux groupes..."
    case "$user_type" in
        "admin")
            for group in "${ADMIN_GROUPS[@]}"; do
                sudo dseditgroup -o edit -a "$username" -t user "$group" 2>/dev/null
            done
            ;;
        "developer")
            for group in "${DEVELOPER_GROUPS[@]}"; do
                sudo dseditgroup -o edit -a "$username" -t user "$group" 2>/dev/null
            done
            ;;
        "standard"|*)
            for group in "${STANDARD_GROUPS[@]}"; do
                sudo dseditgroup -o edit -a "$username" -t user "$group" 2>/dev/null
            done
            ;;
    esac
    
    # Créer et configurer le répertoire home
    echo "Configuration du répertoire home..."
    if [[ ! -d "$home_dir" ]]; then
        sudo mkdir -p "$home_dir"
        sudo chown "$username:staff" "$home_dir"
        sudo chmod 755 "$home_dir"
    fi
    
    # Copier le modèle utilisateur si disponible
    local template_dir="$TEMPLATES_DIR/$user_type"
    if [[ -d "$template_dir" ]]; then
        echo "Application du modèle utilisateur : $user_type"
        sudo cp -R "$template_dir/"* "$home_dir/" 2>/dev/null
        sudo chown -R "$username:staff" "$home_dir"
    fi
    
    # Activer FileVault pour le nouvel utilisateur si requis
    if [[ "$AUTO_FILEVAULT_ENABLE" == "true" ]]; then
        echo "Activation de l'accès FileVault pour l'utilisateur..."
        sudo fdesetup add -usertoadd "$username" 2>/dev/null || true
    fi
    
    # Générer le rapport de profil utilisateur
    local profile_file="$PROVISIONING_DIR/${username}_profile.txt"
    {
        echo "Profil Utilisateur Roundfleet"
        echo "=========================="
        echo "Nom d'utilisateur : $username"
        echo "Nom Réel : $real_name"
        echo "UID : $uid"
        echo "GID : $primary_gid"
        echo "Type Utilisateur : $user_type"
        echo "Département : $department"
        echo "Répertoire Home : $home_dir"
        echo "Shell : $DEFAULT_SHELL"
        echo "Créé : $(date)"
        echo "Créé Par : $admin_user"
        echo "Groupes : $(groups "$username" 2>/dev/null | cut -d: -f2)"
        echo ""
        echo "Paramètres de Sécurité :"
        echo "- FileVault Activé : $AUTO_FILEVAULT_ENABLE"
        echo "- Mot de Passe Sécurisé : $REQUIRE_SECURE_PASSWORDS"
        echo "- Convention de Nommage : $ENFORCE_NAMING_CONVENTION"
    } > "$profile_file"
    
    echo "✅ Création utilisateur terminée avec succès"
    echo "Profil sauvegardé : $profile_file"
    
    log_operation "INFO" "Utilisateur créé avec succès : $username (UID : $uid, Type : $user_type)"
    log_audit_action "USER_CREATION_SUCCESS" "$username" "$admin_user" "uid=$uid,type=$user_type,groups=$(groups "$username" 2>/dev/null | cut -d: -f2)"
    
    return 0
}

# Création utilisateur en masse depuis fichier CSV
bulk_create_users() {
    local csv_file="$1"
    local admin_user=$(whoami)
    
    if [[ ! -f "$csv_file" ]]; then
        echo "Erreur : Fichier CSV non trouvé : $csv_file"
        return 1
    fi
    
    log_audit_action "BULK_CREATION_START" "multiple" "$admin_user" "source=$csv_file"
    
    echo "=== Création Utilisateur en Masse ==="
    echo "Fichier CSV : $csv_file"
    echo "Administrateur : $admin_user"
    echo ""
    
    local line_count=0
    local success_count=0
    local error_count=0
    local results_file="$PROVISIONING_DIR/bulk_creation_$(date +%Y%m%d_%H%M%S).log"
    
    # Lire le fichier CSV (format : nom_utilisateur,nom_reel,type_utilisateur,departement)
    while IFS=',' read -r username real_name user_type department; do
        line_count=$((line_count + 1))
        
        # Ignorer la ligne d'en-tête
        if [[ $line_count -eq 1 && "$username" == "username" ]]; then
            continue
        fi
        
        # Ignorer les lignes vides
        if [[ -z "$username" ]]; then
            continue
        fi
        
        # Générer un mot de passe sécurisé
        local password
        password=$(generate_secure_password 12 "high")
        
        echo "Traitement utilisateur $line_count : $username"
        
        # Créer l'utilisateur
        if create_enterprise_user "$username" "$real_name" "$password" "$user_type" "$department"; then
            success_count=$((success_count + 1))
            echo "SUCCÈS : $username,$real_name,$password,$user_type,$department" >> "$results_file"
        else
            error_count=$((error_count + 1))
            echo "ERREUR : $username,$real_name,ÉCHEC,$user_type,$department" >> "$results_file"
        fi
        
        echo ""
    done < "$csv_file"
    
    echo "=== Résumé Création en Masse ==="
    echo "Total Traité : $line_count"
    echo "Réussis : $success_count"
    echo "Erreurs : $error_count"
    echo "Fichier Résultats : $results_file"
    
    log_operation "INFO" "Création utilisateur en masse terminée : $success_count réussies, $error_count erreurs"
    log_audit_action "BULK_CREATION_COMPLETE" "multiple" "$admin_user" "total=$line_count,success=$success_count,errors=$error_count"
}

# Créer des modèles utilisateur
create_user_template() {
    local template_type="$1"
    local template_dir="$TEMPLATES_DIR/$template_type"
    
    echo "Création du modèle utilisateur : $template_type"
    
    mkdir -p "$template_dir"
    
    case "$template_type" in
        "standard")
            # Modèle utilisateur standard
            mkdir -p "$template_dir/Desktop"
            mkdir -p "$template_dir/Documents"
            mkdir -p "$template_dir/Downloads"
            
            # Créer le document de bienvenue
            cat > "$template_dir/Desktop/Welcome.txt" << EOF
Bienvenue sur Roundfleet !

Votre compte a été configuré avec des privilèges utilisateur standard.
Pour le support, veuillez contacter IT à [email protected]

Type de Compte : Utilisateur Standard
Date de Création : $(date)
EOF
            ;;
        "admin")
            # Modèle utilisateur admin
            mkdir -p "$template_dir/Desktop"
            mkdir -p "$template_dir/Documents/OutilsAdmin"
            mkdir -p "$template_dir/Downloads"
            
            cat > "$template_dir/Desktop/Admin_Welcome.txt" << EOF
Bienvenue sur Roundfleet - Compte Administrateur

Votre compte a été configuré avec des privilèges administratifs.
Veuillez utiliser ces privilèges de manière responsable.

Type de Compte : Administrateur
Date de Création : $(date)

Important :
- Suivez les politiques de sécurité de l'entreprise
- Changements de mot de passe réguliers requis
- Toutes les actions administratives sont enregistrées
EOF
            ;;
        "developer")
            # Modèle utilisateur développeur
            mkdir -p "$template_dir/Desktop"
            mkdir -p "$template_dir/Documents/Projets"
            mkdir -p "$template_dir/Downloads"
            mkdir -p "$template_dir/Development"
            
            cat > "$template_dir/Desktop/Developer_Setup.txt" << EOF
Configuration Compte Développeur

Votre compte inclut l'accès aux outils de développement.

Type de Compte : Développeur
Date de Création : $(date)

Étapes Suivantes :
1. Installer Xcode depuis l'App Store
2. Configurer les identifiants Git
3. Configurer l'environnement de développement
4. Consulter la documentation des standards de codage
EOF
            ;;
    esac
    
    # Définir les permissions du modèle
    chmod -R 755 "$template_dir"
    
    echo "Modèle créé : $template_dir"
    log_operation "INFO" "Modèle utilisateur créé : $template_type"
}

# Générer un rapport de provisioning
generate_provisioning_report() {
    local report_type="${1:-resume}"
    local admin_user=$(whoami)
    local report_file="$PROVISIONING_DIR/provisioning_report_$(date +%Y%m%d_%H%M%S).txt"
    
    log_audit_action "PROVISIONING_REPORT" "system" "$admin_user" "type=$report_type"
    
    {
        echo "Rapport de Provisioning Utilisateur Roundfleet"
        echo "==========================================="
        echo "Type de Rapport : $report_type"
        echo "Généré : $(date)"
        echo "Généré Par : $admin_user"
        echo "Nom d'hôte : $(hostname)"
        echo ""
        
        case "$report_type" in
            "resume")
                echo "== Résumé de Provisioning =="
                local total_users=$(dscl . list /Users | grep -v '^_' | wc -l)
                local recent_users=$(find "$PROVISIONING_DIR" -name "*_profile.txt" -mtime -7 | wc -l)
                
                echo "Total Utilisateurs : $total_users"
                echo "Utilisateurs Créés (7 derniers jours) : $recent_users"
                echo ""
                
                echo "Distribution Type Utilisateur :"
                echo "Utilisateurs Standard : $(dscl . list /Users | xargs -I {} dscl . read /Users/{} PrimaryGroupID 2>/dev/null | grep -c '20')"
                echo "Utilisateurs Admin : $(dscl . list /Users | xargs -I {} dscl . read /Users/{} PrimaryGroupID 2>/dev/null | grep -c '80')"
                ;;
            "recent")
                echo "== Créations Utilisateur Récentes =="
                echo "Utilisateurs créés dans les 30 derniers jours :"
                find "$PROVISIONING_DIR" -name "*_profile.txt" -mtime -30 -exec basename {} \; | sed 's/_profile.txt//'
                ;;
            "audit")
                echo "== Information d'Audit =="
                if [[ -f "$AUDIT_LOG" ]]; then
                    echo "Activités de provisioning récentes :"
                    grep "USER_CREATION" "$AUDIT_LOG" | tail -10
                else
                    echo "Aucun log d'audit disponible"
                fi
                ;;
        esac
        
        echo ""
        echo "== Configuration =="
        echo "UID Min : $MIN_UID"
        echo "UID Max : $MAX_UID"
        echo "Shell Par Défaut : $DEFAULT_SHELL"
        echo "FileVault Auto : $AUTO_FILEVAULT_ENABLE"
        echo "Mots de Passe Sécurisés : $REQUIRE_SECURE_PASSWORDS"
        echo "Convention Nommage : $ENFORCE_NAMING_CONVENTION"
        
    } > "$report_file"
    
    echo "Rapport de provisioning généré : $report_file"
    log_operation "INFO" "Rapport de provisioning généré : $report_file"
}

# Fonction principale de gestion de création utilisateur
main() {
    local action="${1:-help}"
    
    case "$action" in
        "create")
            local username="$2"
            local real_name="$3"
            local password="$4"
            local user_type="${5:-standard}"
            local department="${6:-General}"
            
            if [[ -z "$username" || -z "$real_name" ]]; then
                echo "Usage : $0 create <nom_utilisateur> <nom_reel> [mot_de_passe] [type_utilisateur] [departement]"
                echo "Types utilisateur : standard, admin, developer"
                exit 1
            fi
            
            # Générer un mot de passe si non fourni
            if [[ -z "$password" ]]; then
                password=$(generate_secure_password 12 "high")
                echo "Mot de passe sécurisé généré : $password"
            fi
            
            create_enterprise_user "$username" "$real_name" "$password" "$user_type" "$department"
            ;;
        "bulk")
            local csv_file="$2"
            
            if [[ -z "$csv_file" ]]; then
                echo "Usage : $0 bulk <fichier_csv>"
                echo "Format CSV : nom_utilisateur,nom_reel,type_utilisateur,departement"
                exit 1
            fi
            
            bulk_create_users "$csv_file"
            ;;
        "template")
            local template_type="$2"
            
            if [[ -z "$template_type" ]]; then
                echo "Usage : $0 template <type_modele>"
                echo "Types de modèle : standard, admin, developer"
                exit 1
            fi
            
            create_user_template "$template_type"
            ;;
        "report")
            local report_type="${2:-resume}"
            
            generate_provisioning_report "$report_type"
            ;;
        "password")
            local length="${2:-12}"
            local complexity="${3:-high}"
            
            echo "Mot de passe généré : $(generate_secure_password "$length" "$complexity")"
            ;;
        "help"|*)
            echo "$SCRIPT_NAME v$VERSION"
            echo "Gestion Entreprise de Création Utilisateur"
            echo ""
            echo "Usage : $0 <action> [options]"
            echo ""
            echo "Actions :"
            echo "  create <nom_utilisateur> <nom_reel> [mot_de_passe] [type] [dept]  - Créer un utilisateur unique"
            echo "  bulk <fichier_csv>                                               - Créer des utilisateurs depuis CSV"
            echo "  template <type>                                                  - Créer un modèle utilisateur"
            echo "  report [type]                                                    - Générer des rapports de provisioning"
            echo "  password [longueur] [complexite]                                - Générer un mot de passe sécurisé"
            echo "  help                                                             - Afficher ce message d'aide"
            echo ""
            echo "Types Utilisateur :"
            echo "  standard    - Utilisateur standard avec privilèges de base"
            echo "  admin       - Utilisateur administratif avec privilèges élevés"
            echo "  developer   - Utilisateur développeur avec accès aux outils de développement"
            echo ""
            echo "Types de Rapport :"
            echo "  resume      - Aperçu du provisioning utilisateur (défaut)"
            echo "  recent      - Utilisateurs récemment créés"
            echo "  audit       - Information de piste d'audit"
            echo ""
            echo "Complexité Mot de Passe :"
            echo "  basic       - Minuscules et chiffres uniquement"
            echo "  medium      - Lettres et chiffres"
            echo "  high        - Lettres, chiffres et symboles (défaut)"
            echo ""
            echo "Fonctionnalités :"
            echo "  • Provisioning utilisateur automatisé avec modèles entreprise"
            echo "  • Création de comptes axée sécurité avec validation"
            echo "  • Création utilisateur en masse depuis fichiers CSV"
            echo "  • Journalisation d'audit complète et conformité"
            echo "  • Intégration avec FileVault et sécurité entreprise"
            echo "  • Intégration utilisateur basée sur modèles"
            echo "  • Génération et validation automatisées de mots de passe"
            ;;
    esac
}

# Exécuter la fonction principale avec tous les arguments
main "$@"

Commandes de Référence Rapide

Création Utilisateur Unique

# Créer un utilisateur standard
./user_creator.sh create jean.dupont "Jean Dupont"

# Créer un utilisateur admin avec mot de passe personnalisé
./user_creator.sh create admin.utilisateur "Utilisateur Admin" "MotDePasseSecurise123!" admin IT

# Créer un utilisateur développeur
./user_creator.sh create dev.utilisateur "Utilisateur Développeur" "" developer Ingenierie

# Créer un utilisateur avec tous les paramètres
./user_creator.sh create jane.smith "Jane Smith" "MotDePassePerso456!" standard Marketing

Opérations Utilisateur en Masse

# Créer des utilisateurs depuis un fichier CSV
./user_creator.sh bulk utilisateurs.csv

# Exemple de format CSV :
# nom_utilisateur,nom_reel,type_utilisateur,departement
# jean.dupont,Jean Dupont,standard,Ventes
# jane.admin,Jane Admin,admin,IT
# dev.utilisateur,Utilisateur Dev,developer,Ingenierie

Gestion de Modèles

# Créer un modèle utilisateur standard
./user_creator.sh template standard

# Créer un modèle utilisateur admin
./user_creator.sh template admin

# Créer un modèle utilisateur développeur
./user_creator.sh template developer

Génération de Mot de Passe

# Générer un mot de passe haute complexité (défaut)
./user_creator.sh password

# Générer un mot de passe de 16 caractères
./user_creator.sh password 16

# Générer un mot de passe complexité moyenne
./user_creator.sh password 12 medium

# Générer un mot de passe basique
./user_creator.sh password 10 basic

Opérations de Rapport

# Générer un rapport résumé
./user_creator.sh report

# Générer un rapport utilisateurs récents
./user_creator.sh report recent

# Générer un rapport d'audit
./user_creator.sh report audit

Exemples d'Intégration

Intégration JAMF Pro

#!/bin/bash

# Script JAMF Pro pour création utilisateur entreprise
# Paramètres : $4 = nom_utilisateur, $5 = nom_reel, $6 = type_utilisateur, $7 = departement

NOM_UTILISATEUR="$4"
NOM_REEL="$5"
TYPE_UTILISATEUR="$6"
DEPARTEMENT="$7"

# Télécharger le créateur utilisateur s'il n'est pas présent
if [[ ! -f "/usr/local/bin/roundfleet_user_creator.sh" ]]; then
    curl -o "/usr/local/bin/roundfleet_user_creator.sh" \
         "https://scripts.roundfleet.com/user_creator.sh"
    chmod +x "/usr/local/bin/roundfleet_user_creator.sh"
fi

# Créer l'utilisateur avec paramètres entreprise
/usr/local/bin/roundfleet_user_creator.sh create \
    "$NOM_UTILISATEUR" "$NOM_REEL" "" "$TYPE_UTILISATEUR" "$DEPARTEMENT"

# Rapporter le statut à JAMF
if [[ $? -eq 0 ]]; then
    echo "Utilisateur $NOM_UTILISATEUR créé avec succès"
    exit 0
else
    echo "Échec de création de l'utilisateur $NOM_UTILISATEUR"
    exit 1
fi

Fonctionnalités de Sécurité et Conformité

Application de Politique de Mot de Passe

# Validation avancée de politique de mot de passe
enforce_enterprise_password_policy() {
    local password="$1"
    local username="$2"
    
    # Vérifier contre les mots de passe communs
    local common_passwords=("password" "123456" "admin" "welcome")
    for common in "${common_passwords[@]}"; do
        if [[ "${password,,}" == "${common,,}" ]]; then
            echo "Erreur : Mot de passe trop commun"
            return 1
        fi
    done
    
    # Vérifier le nom d'utilisateur dans le mot de passe
    if [[ "${password,,}" =~ ${username,,} ]]; then
        echo "Erreur : Le mot de passe ne peut pas contenir le nom d'utilisateur"
        return 1
    fi
    
    # Vérifier l'historique des mots de passe (si implémenté)
    check_password_history "$username" "$password"
}

Rapport d'Audit et Conformité

# Générer un rapport de conformité pour la création utilisateur
generate_compliance_report() {
    local start_date="$1"
    local end_date="$2"
    local report_file="/var/reports/user_creation_compliance_$(date +%Y%m%d).json"
    
    {
        echo "{"
        echo "  \"report_type\": \"user_creation_compliance\","
        echo "  \"period\": \"$start_date à $end_date\","
        echo "  \"generated\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\","
        echo "  \"total_users_created\": $(grep "USER_CREATION_SUCCESS" "$AUDIT_LOG" | wc -l),"
        echo "  \"policy_violations\": $(grep "POLICY_VIOLATION" "$AUDIT_LOG" | wc -l),"
        echo "  \"security_reviews\": $(grep "SECURITY_REVIEW" "$AUDIT_LOG" | wc -l)"
        echo "}"
    } > "$report_file"
    
    echo "Rapport de conformité généré : $report_file"
}

Meilleures Pratiques

  1. Utiliser des politiques de mots de passe forts avec exigences de complexité
  2. Implémenter des types d'utilisateur basés sur les rôles pour attribution appropriée des privilèges
  3. Activer la journalisation d'audit complète pour toutes les activités de création utilisateur
  4. Utiliser des modèles pour des expériences d'intégration utilisateur cohérentes
  5. Intégrer avec les services d'annuaire d'entreprise pour une gestion centralisée
  6. Automatiser l'inscription FileVault pour la conformité de sécurité
  7. Générer des rapports de conformité réguliers à des fins d'audit
  8. Valider les noms d'utilisateur selon les conventions de nommage d'entreprise

Ce système de gestion de création utilisateur entreprise fournit des capacités de provisioning utilisateur complètes avec contrôles de sécurité, conformité d'audit et workflows automatisés pour une gestion efficace du cycle de vie utilisateur Roundfleet.

Gestion des Comptes Utilisateurs sur macOS

Maîtrisez la création et la gestion des comptes utilisateurs sur vos appareils Roundfleet en utilisant des outils en ligne de commande puissants. Ce tutoriel couvre la création d'utilisateurs administrateurs et standards, la gestion des mots de passe, la configuration des comptes et la gestion avancée du cycle de vie des utilisateurs pour les déploiements en entreprise.

Comprendre la Gestion des Utilisateurs macOS

macOS fournit plusieurs outils en ligne de commande pour la gestion des comptes utilisateurs :

  • sysadminctl - Outil moderne de gestion des comptes utilisateurs (macOS 10.10+)
  • dscl - Utilitaire en ligne de commande des services d'annuaire pour les opérations avancées
  • passwd - Gestion et changement des mots de passe
  • id - Affichage des informations utilisateur et groupe
  • whoami - Identification de l'utilisateur actuel

Création Basique de Comptes Utilisateurs

Créer un Compte Utilisateur Administrateur

#!/bin/sh

# Définir la variable d'environnement PATH
export PATH=/usr/bin:/bin:/usr/sbin:/sbin

# Configuration utilisateur administrateur
USERNAME="Daniel"
FULLNAME="Daniel.Hector"
PASSWORD="One@Two#8"
PASSWORDHINT="One to Eight"

# Créer un compte utilisateur administrateur
sysadminctl -addUser "$USERNAME" -fullName "$FULLNAME" -password "$PASSWORD" -hint "$PASSWORDHINT" -admin

echo "Compte utilisateur administrateur '$USERNAME' créé avec succès"

Créer un Compte Utilisateur Standard

#!/bin/sh

# Définir la variable d'environnement PATH
export PATH=/usr/bin:/bin:/usr/sbin:/sbin

# Configuration utilisateur standard
USERNAME="Daniel"
FULLNAME="Daniel.Hector"
PASSWORD="One@Two#8"
PASSWORDHINT="One to Eight"

# Créer un compte utilisateur standard (pas de flag -admin)
sysadminctl -addUser "$USERNAME" -fullName "$FULLNAME" -password "$PASSWORD" -hint "$PASSWORDHINT"

echo "Compte utilisateur standard '$USERNAME' créé avec succès"

Création d'Utilisateur Améliorée avec Validation

#!/bin/bash

# Création d'utilisateur améliorée avec validation
create_user_account() {
    local username="$1"
    local fullname="$2"
    local password="$3"
    local hint="$4"
    local is_admin="${5:-false}"
    
    # Valider les entrées
    if [[ -z "$username" || -z "$fullname" || -z "$password" ]]; then
        echo "Erreur : Le nom d'utilisateur, le nom complet et le mot de passe sont requis"
        return 1
    fi
    
    # Vérifier si l'utilisateur existe déjà
    if id "$username" &>/dev/null; then
        echo "Erreur : L'utilisateur '$username' existe déjà"
        return 1
    fi
    
    # Définir l'environnement PATH
    export PATH=/usr/bin:/bin:/usr/sbin:/sbin
    
    # Construire la commande sysadminctl
    local cmd="sysadminctl -addUser \"$username\" -fullName \"$fullname\" -password \"$password\""
    
    if [[ -n "$hint" ]]; then
        cmd="$cmd -hint \"$hint\""
    fi
    
    if [[ "$is_admin" == "true" ]]; then
        cmd="$cmd -admin"
        echo "Création d'un utilisateur administrateur : $username"
    else
        echo "Création d'un utilisateur standard : $username"
    fi
    
    # Exécuter la création d'utilisateur
    if eval "$cmd"; then
        echo "✓ Utilisateur '$username' créé avec succès"
        
        # Afficher les informations utilisateur
        echo "Détails de l'utilisateur :"
        id "$username"
        return 0
    else
        echo "✗ Échec de la création de l'utilisateur '$username'"
        return 1
    fi
}

# Exemples d'utilisation
create_user_account "daniel" "Daniel Hector" "SecurePass123!" "Indice de mot de passe" "true"
create_user_account "jane" "Jane Smith" "UserPass456!" "Autre indice" "false"

Gestion Avancée des Utilisateurs

Création d'Utilisateurs en Lot

#!/bin/bash

# Création d'utilisateurs en lot à partir de configuration
batch_create_users() {
    local config_file="$1"
    
    if [[ ! -f "$config_file" ]]; then
        echo "Erreur : Fichier de configuration introuvable : $config_file"
        return 1
    fi
    
    echo "=== Création d'Utilisateurs en Lot ==="
    
    local success_count=0
    local error_count=0
    
    # Lire le fichier de configuration (format : username,fullname,password,hint,admin)
    while IFS=',' read -r username fullname password hint is_admin; do
        # Ignorer les lignes vides et les commentaires
        [[ -z "$username" || "$username" =~ ^# ]] && continue
        
        echo "Traitement de l'utilisateur : $username"
        
        if create_user_account "$username" "$fullname" "$password" "$hint" "$is_admin"; then
            ((success_count++))
        else
            ((error_count++))
        fi
        
        echo "---"
    done < "$config_file"
    
    echo "Création en lot terminée :"
    echo "✓ Succès : $success_count utilisateurs"
    echo "✗ Erreurs : $error_count utilisateurs"
}

# Créer un fichier de configuration exemple
create_user_config() {
    local config_file="/tmp/users_config.csv"
    
    cat > "$config_file" << EOF
# Format : username,fullname,password,hint,admin(true/false)
daniel,Daniel Hector,SecurePass123!,Indice de mot de passe,true
jane,Jane Smith,UserPass456!,Autre indice,false
alex,Alex Johnson,TempPass789!,Mot de passe temporaire,false
admin,Administrateur Système,AdminPass000!,Accès administrateur,true
EOF
    
    echo "Configuration exemple créée : $config_file"
    echo "$config_file"
}

# Utilisation
config_file=$(create_user_config)
batch_create_users "$config_file"

Modification de Comptes Utilisateurs

#!/bin/bash

# Modifier les comptes utilisateurs existants
modify_user_account() {
    local username="$1"
    local action="$2"
    local value="$3"
    
    # Vérifier que l'utilisateur existe
    if ! id "$username" &>/dev/null; then
        echo "Erreur : L'utilisateur '$username' n'existe pas"
        return 1
    fi
    
    export PATH=/usr/bin:/bin:/usr/sbin:/sbin
    
    case "$action" in
        "password")
            echo "Changement de mot de passe pour l'utilisateur : $username"
            if sysadminctl -resetPasswordFor "$username" -newPassword "$value"; then
                echo "✓ Mot de passe changé avec succès"
            else
                echo "✗ Échec du changement de mot de passe"
                return 1
            fi
            ;;
        "fullname")
            echo "Changement du nom complet pour l'utilisateur : $username"
            if dscl . -change "/Users/$username" RealName "$(dscl . -read "/Users/$username" RealName | cut -d: -f2 | xargs)" "$value"; then
                echo "✓ Nom complet changé en : $value"
            else
                echo "✗ Échec du changement de nom complet"
                return 1
            fi
            ;;
        "admin")
            if [[ "$value" == "true" ]]; then
                echo "Attribution des privilèges administrateur à : $username"
                if dseditgroup -o edit -a "$username" -t user admin; then
                    echo "✓ Privilèges administrateur attribués"
                else
                    echo "✗ Échec de l'attribution des privilèges administrateur"
                    return 1
                fi
            else
                echo "Suppression des privilèges administrateur de : $username"
                if dseditgroup -o edit -d "$username" -t user admin; then
                    echo "✓ Privilèges administrateur supprimés"
                else
                    echo "✗ Échec de la suppression des privilèges administrateur"
                    return 1
                fi
            fi
            ;;
        "enable")
            echo "Activation du compte utilisateur : $username"
            if dscl . -create "/Users/$username" AuthenticationAuthority; then
                echo "✓ Compte utilisateur activé"
            else
                echo "✗ Échec de l'activation du compte utilisateur"
                return 1
            fi
            ;;
        "disable")
            echo "Désactivation du compte utilisateur : $username"
            if dscl . -delete "/Users/$username" AuthenticationAuthority; then
                echo "✓ Compte utilisateur désactivé"
            else
                echo "✗ Échec de la désactivation du compte utilisateur"
                return 1
            fi
            ;;
        *)
            echo "Erreur : Action inconnue '$action'"
            echo "Actions disponibles : password, fullname, admin, enable, disable"
            return 1
            ;;
    esac
}

# Exemples d'utilisation
modify_user_account "daniel" "password" "NewSecurePass123!"
modify_user_account "jane" "admin" "true"
modify_user_account "alex" "fullname" "Alexander Johnson"

Suppression de Comptes Utilisateurs

#!/bin/bash

# Supprimer les comptes utilisateurs avec options
delete_user_account() {
    local username="$1"
    local delete_home="${2:-true}"
    local backup_home="${3:-false}"
    
    # Vérifier que l'utilisateur existe
    if ! id "$username" &>/dev/null; then
        echo "Erreur : L'utilisateur '$username' n'existe pas"
        return 1
    fi
    
    # Empêcher la suppression d'utilisateurs système critiques
    local system_users=("root" "daemon" "nobody" "_www" "_mysql" "_postgresql")
    for sys_user in "${system_users[@]}"; do
        if [[ "$username" == "$sys_user" ]]; then
            echo "Erreur : Impossible de supprimer l'utilisateur système '$username'"
            return 1
        fi
    done
    
    export PATH=/usr/bin:/bin:/usr/sbin:/sbin
    
    echo "Préparation de la suppression de l'utilisateur : $username"
    
    # Sauvegarder le répertoire home si demandé
    if [[ "$backup_home" == "true" ]]; then
        local backup_dir="/var/backups/deleted_users"
        local timestamp=$(date +%Y%m%d_%H%M%S)
        local backup_path="$backup_dir/${username}_${timestamp}.tar.gz"
        
        mkdir -p "$backup_dir"
        
        echo "Sauvegarde du répertoire home vers : $backup_path"
        if tar -czf "$backup_path" -C "/Users" "$username" 2>/dev/null; then
            echo "✓ Répertoire home sauvegardé"
        else
            echo "⚠ Attention : Échec de la sauvegarde du répertoire home"
        fi
    fi
    
    # Supprimer le compte utilisateur
    local delete_cmd="sysadminctl -deleteUser \"$username\""
    
    if [[ "$delete_home" == "true" ]]; then
        delete_cmd="$delete_cmd -secure"
        echo "Suppression de l'utilisateur et du répertoire home..."
    else
        echo "Suppression du compte utilisateur uniquement..."
    fi
    
    if eval "$delete_cmd"; then
        echo "✓ Utilisateur '$username' supprimé avec succès"
        return 0
    else
        echo "✗ Échec de la suppression de l'utilisateur '$username'"
        return 1
    fi
}

# Exemples d'utilisation
delete_user_account "testuser" "true" "true"  # Supprimer avec home, sauvegarder d'abord
delete_user_account "tempuser" "false" "false"  # Supprimer utilisateur seulement, pas de sauvegarde

Système de Gestion d'Utilisateurs en Entreprise

#!/bin/bash

# Outil de Gestion d'Utilisateurs Roundfleet
# Gestion complète des comptes utilisateurs pour les appareils de flotte

# Configuration
SCRIPT_VERSION="1.0.0"
LOG_FILE="/var/log/roundfleet_users.log"
REPORT_DIR="/etc/roundfleet/reports/users"
CONFIG_DIR="/etc/roundfleet/users"
BACKUP_DIR="/var/backups/roundfleet_users"

# Créer les répertoires s'ils n'existent pas
mkdir -p "$REPORT_DIR" "$CONFIG_DIR" "$BACKUP_DIR"

# Catégories de comptes utilisateurs
declare -A USER_CATEGORIES=(
    ["administrator"]="admin,full_privileges,system_access"
    ["developer"]="standard,sudo_group,development_access"
    ["standard_user"]="standard,basic_privileges,user_access"
    ["service_account"]="standard,no_login,service_access"
    ["temporary_user"]="standard,limited_time,restricted_access"
    ["guest_user"]="standard,guest_privileges,temporary_access"
    ["kiosk_user"]="standard,kiosk_mode,restricted_access"
    ["backup_operator"]="standard,backup_privileges,system_access"
    ["monitoring_user"]="standard,read_only,monitoring_access"
    ["deployment_user"]="admin,deployment_privileges,automated_access"
)

# Politiques de gestion d'utilisateurs
declare -A USER_POLICIES=(
    ["password_strength"]="minimum_8_chars,mixed_case,numbers,special_chars"
    ["password_expiry"]="90_days,180_days,365_days,never"
    ["account_lockout"]="3_attempts,5_attempts,10_attempts,disabled"
    ["session_timeout"]="15_minutes,30_minutes,60_minutes,4_hours"
    ["home_directory"]="local_only,network_shared,encrypted,no_home"
    ["shell_access"]="/bin/bash,/bin/zsh,/usr/bin/false,/sbin/nologin"
)

# Fonction de journalisation
log_action() {
    local message="$1"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo "[$timestamp] $message" | tee -a "$LOG_FILE"
}

# Création d'utilisateur améliorée avec fonctionnalités d'entreprise
create_enterprise_user() {
    local username="$1"
    local fullname="$2"
    local password="$3"
    local category="${4:-standard_user}"
    local custom_options="$5"
    
    log_action "Création d'utilisateur d'entreprise : $username (Catégorie : $category)"
    
    # Valider les entrées
    if [[ -z "$username" || -z "$fullname" || -z "$password" ]]; then
        log_action "ERREUR : Le nom d'utilisateur, le nom complet et le mot de passe sont requis"
        return 1
    fi
    
    # Vérifier si l'utilisateur existe déjà
    if id "$username" &>/dev/null; then
        log_action "ERREUR : L'utilisateur '$username' existe déjà"
        return 1
    fi
    
    # Valider la force du mot de passe
    if ! validate_password_strength "$password"; then
        log_action "ERREUR : Le mot de passe ne respecte pas les exigences de force"
        return 1
    fi
    
    # Générer un UID unique
    local new_uid=$(get_next_available_uid)
    
    # Créer un compte utilisateur basé sur la catégorie
    export PATH=/usr/bin:/bin:/usr/sbin:/sbin
    
    local is_admin="false"
    local shell="/bin/bash"
    local home_dir="/Users/$username"
    
    # Analyser la configuration de catégorie
    IFS=',' read -ra CATEGORY_PARTS <<< "${USER_CATEGORIES[$category]}"
    local user_type="${CATEGORY_PARTS[0]}"
    local privileges="${CATEGORY_PARTS[1]}"
    local access_level="${CATEGORY_PARTS[2]}"
    
    [[ "$user_type" == "admin" ]] && is_admin="true"
    [[ "$privileges" == "no_login" ]] && shell="/usr/bin/false"
    
    # Créer le compte utilisateur
    local create_cmd="sysadminctl -addUser \"$username\" -fullName \"$fullname\" -password \"$password\" -UID \"$new_uid\""
    
    if [[ "$is_admin" == "true" ]]; then
        create_cmd="$create_cmd -admin"
    fi
    
    if eval "$create_cmd"; then
        log_action "SUCCÈS : Utilisateur '$username' créé avec UID $new_uid"
        
        # Appliquer des configurations supplémentaires
        configure_user_environment "$username" "$category" "$custom_options"
        
        # Générer un rapport utilisateur
        local report_file="$REPORT_DIR/user_creation_${username}_$(date +%Y%m%d_%H%M%S).json"
        generate_user_report "$username" "$report_file"
        
        echo "$report_file"
        return 0
    else
        log_action "ERREUR : Échec de la création de l'utilisateur '$username'"
        return 1
    fi
}

# Validation de la force du mot de passe
validate_password_strength() {
    local password="$1"
    local min_length=8
    
    # Vérifier la longueur minimale
    if [[ ${#password} -lt $min_length ]]; then
        echo "Le mot de passe doit contenir au moins $min_length caractères"
        return 1
    fi
    
    # Vérifier la présence d'une majuscule
    if [[ ! "$password" =~ [A-Z] ]]; then
        echo "Le mot de passe doit contenir au moins une majuscule"
        return 1
    fi
    
    # Vérifier la présence d'une minuscule
    if [[ ! "$password" =~ [a-z] ]]; then
        echo "Le mot de passe doit contenir au moins une minuscule"
        return 1
    fi
    
    # Vérifier la présence d'un chiffre
    if [[ ! "$password" =~ [0-9] ]]; then
        echo "Le mot de passe doit contenir au moins un chiffre"
        return 1
    fi
    
    # Vérifier la présence d'un caractère spécial
    if [[ ! "$password" =~ [^a-zA-Z0-9] ]]; then
        echo "Le mot de passe doit contenir au moins un caractère spécial"
        return 1
    fi
    
    return 0
}

# Obtenir le prochain UID disponible
get_next_available_uid() {
    local start_uid=1000
    local max_uid=65533
    
    for ((uid=start_uid; uid<=max_uid; uid++)); do
        if ! id -u "$uid" &>/dev/null; then
            echo "$uid"
            return 0
        fi
    done
    
    echo "65534"  # UID de secours
}

# Configurer l'environnement utilisateur basé sur la catégorie
configure_user_environment() {
    local username="$1"
    local category="$2"
    local custom_options="$3"
    
    log_action "Configuration de l'environnement pour l'utilisateur : $username (Catégorie : $category)"
    
    case "$category" in
        "developer")
            # Ajouter au groupe développeur
            dseditgroup -o create -q developer 2>/dev/null
            dseditgroup -o edit -a "$username" -t user developer
            
            # Accorder l'accès sudo pour le développement
            echo "$username ALL=(ALL) NOPASSWD: /usr/bin/xcodebuild, /usr/local/bin/brew" > "/etc/sudoers.d/$username"
            ;;
        "service_account")
            # Désactiver le shell de connexion
            dscl . -create "/Users/$username" UserShell /usr/bin/false
            
            # Masquer de la fenêtre de connexion
            dscl . -create "/Users/$username" IsHidden 1
            ;;
        "kiosk_user")
            # Configurer l'environnement kiosk
            setup_kiosk_user "$username"
            ;;
        "temporary_user")
            # Définir l'expiration du compte (30 jours)
            local expiry_date=$(date -v +30d +%Y-%m-%d)
            dscl . -create "/Users/$username" AccountExpires "$expiry_date"
            ;;
    esac
    
    # Appliquer les options personnalisées si fournies
    if [[ -n "$custom_options" ]]; then
        apply_custom_user_options "$username" "$custom_options"
    fi
}

# Configurer l'environnement utilisateur kiosk
setup_kiosk_user() {
    local username="$1"
    local kiosk_dir="/Users/$username/Desktop"
    
    # Créer l'environnement desktop kiosk
    mkdir -p "$kiosk_dir"
    
    # Créer le plist launchd pour le mode kiosk
    cat > "/Library/LaunchAgents/com.roundfleet.kiosk.$username.plist" << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.roundfleet.kiosk.$username</string>
    <key>ProgramArguments</key>
    <array>
        <string>/System/Applications/Safari.app/Contents/MacOS/Safari</string>
        <string>--kiosk</string>
        <string>https://company-portal.example.com</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>UserName</key>
    <string>$username</string>
</dict>
</plist>
EOF
    
    chown "$username:staff" "/Library/LaunchAgents/com.roundfleet.kiosk.$username.plist"
    chmod 644 "/Library/LaunchAgents/com.roundfleet.kiosk.$username.plist"
}

# Générer un rapport utilisateur
generate_user_report() {
    local username="$1"
    local report_file="$2"
    
    # Obtenir les informations utilisateur
    local user_info=$(id "$username")
    local user_groups=$(groups "$username")
    local home_dir=$(dscl . -read "/Users/$username" NFSHomeDirectory | cut -d: -f2 | xargs)
    local shell=$(dscl . -read "/Users/$username" UserShell | cut -d: -f2 | xargs)
    local real_name=$(dscl . -read "/Users/$username" RealName | cut -d: -f2 | xargs)
    
    cat > "$report_file" << EOF
{
    "user_report": {
        "username": "$username",
        "timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
        "hostname": "$(hostname)",
        "script_version": "$SCRIPT_VERSION",
        "user_details": {
            "real_name": "$real_name",
            "home_directory": "$home_dir",
            "shell": "$shell",
            "user_info": "$user_info",
            "groups": "$user_groups"
        },
        "creation_status": "success",
        "security_settings": {
            "password_policy_applied": true,
            "account_restrictions": [],
            "group_memberships": []
        }
    }
}
EOF
    
    log_action "Rapport utilisateur généré : $report_file"
}

# Gestion d'utilisateurs de flotte
manage_fleet_users() {
    local action="$1"
    local target_spec="$2"
    local options="$3"
    
    log_action "Gestion d'utilisateurs de flotte : $action"
    
    case "$action" in
        "audit")
            audit_fleet_users "$target_spec"
            ;;
        "sync")
            sync_fleet_users "$target_spec" "$options"
            ;;
        "cleanup")
            cleanup_fleet_users "$target_spec" "$options"
            ;;
        "report")
            generate_fleet_user_report
            ;;
    esac
}

# Auditer tous les utilisateurs du système
audit_fleet_users() {
    local filter_pattern="$1"
    
    echo "=== Audit des Utilisateurs de Flotte ==="
    
    local audit_report="$REPORT_DIR/fleet_user_audit_$(date +%Y%m%d_%H%M%S).json"
    
    cat > "$audit_report" << EOF
{
    "audit_info": {
        "timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
        "hostname": "$(hostname)",
        "filter_pattern": "$filter_pattern"
    },
    "user_accounts": [],
    "security_summary": {},
    "recommendations": []
}
EOF
    
    # Obtenir tous les utilisateurs locaux
    local users=($(dscl . -list /Users | grep -v "^_" | grep -v "daemon\|nobody\|root"))
    
    for user in "${users[@]}"; do
        if [[ -z "$filter_pattern" || "$user" =~ $filter_pattern ]]; then
            # Obtenir les informations utilisateur détaillées
            local uid=$(id -u "$user" 2>/dev/null)
            local gid=$(id -g "$user" 2>/dev/null)
            local groups=$(groups "$user" 2>/dev/null)
            local home=$(dscl . -read "/Users/$user" NFSHomeDirectory 2>/dev/null | cut -d: -f2 | xargs)
            local shell=$(dscl . -read "/Users/$user" UserShell 2>/dev/null | cut -d: -f2 | xargs)
            local last_login=$(last -1 "$user" | head -1 | awk '{print $4, $5, $6, $7}')
            
            # Vérifier si l'utilisateur est administrateur
            local is_admin="false"
            if dseditgroup -o checkmember -m "$user" admin &>/dev/null; then
                is_admin="true"
            fi
            
            # Ajouter au rapport
            jq --arg user "$user" \
               --arg uid "$uid" \
               --arg gid "$gid" \
               --arg groups "$groups" \
               --arg home "$home" \
               --arg shell "$shell" \
               --arg last_login "$last_login" \
               --arg is_admin "$is_admin" \
               '.user_accounts += [{
                   "username": $user,
                   "uid": $uid,
                   "gid": $gid,
                   "groups": $groups,
                   "home_directory": $home,
                   "shell": $shell,
                   "last_login": $last_login,
                   "is_admin": ($is_admin == "true")
               }]' "$audit_report" > "${audit_report}.tmp" && mv "${audit_report}.tmp" "$audit_report"
        fi
    done
    
    # Générer un résumé de sécurité
    local total_users=$(echo "${users[@]}" | wc -w)
    local admin_users=$(dseditgroup -o checkmember -m "" admin 2>/dev/null | wc -l)
    local inactive_users=0
    
    # Vérifier les utilisateurs inactifs (pas de connexion depuis 90 jours)
    for user in "${users[@]}"; do
        local last_login_timestamp=$(last -1 "$user" | head -1 | awk '{print $4, $5, $6, $7}')
        if [[ -n "$last_login_timestamp" ]]; then
            local days_since_login=$(( ($(date +%s) - $(date -j -f "%b %d %H:%M" "$last_login_timestamp" +%s 2>/dev/null || echo 0)) / 86400 ))
            if [[ $days_since_login -gt 90 ]]; then
                ((inactive_users++))
            fi
        fi
    done
    
    jq --argjson total "$total_users" \
       --argjson admins "$admin_users" \
       --argjson inactive "$inactive_users" \
       '.security_summary = {
           "total_users": $total,
           "admin_users": $admins,
           "inactive_users": $inactive,
           "security_score": (100 - ($admins * 10) - ($inactive * 5))
       }' "$audit_report" > "${audit_report}.tmp" && mv "${audit_report}.tmp" "$audit_report"
    
    log_action "Audit des utilisateurs de flotte terminé : $audit_report"
    echo "$audit_report"
}

# Fonction d'exécution principale
main() {
    local action="${1:-create}"
    local username="${2:-}"
    local fullname="${3:-}"
    local password="${4:-}"
    local options="${5:-}"
    
    log_action "=== Gestion d'Utilisateurs Roundfleet Démarrée ==="
    log_action "Action : $action, Utilisateur : $username"
    
    case "$action" in
        "create")
            if [[ -z "$username" || -z "$fullname" || -z "$password" ]]; then
                echo "Utilisation : $0 create <username> <fullname> <password> [category]"
                exit 1
            fi
            create_enterprise_user "$username" "$fullname" "$password" "$options"
            ;;
        "modify")
            if [[ -z "$username" || -z "$fullname" ]]; then
                echo "Utilisation : $0 modify <username> <action> <value>"
                exit 1
            fi
            modify_user_account "$username" "$fullname" "$password"
            ;;
        "delete")
            if [[ -z "$username" ]]; then
                echo "Utilisation : $0 delete <username> [delete_home] [backup_home]"
                exit 1
            fi
            delete_user_account "$username" "$fullname" "$password"
            ;;
        "audit")
            audit_fleet_users "$username"
            ;;
        "fleet")
            manage_fleet_users "$username" "$fullname" "$password"
            ;;
        "help")
            echo "Utilisation : $0 [action] [options...]"
            echo "Actions :"
            echo "  create <username> <fullname> <password> [category] - Créer utilisateur"
            echo "  modify <username> <action> <value> - Modifier utilisateur"
            echo "  delete <username> [delete_home] [backup_home] - Supprimer utilisateur"
            echo "  audit [pattern] - Auditer utilisateurs"
            echo "  fleet <action> [pattern] [options] - Gestion de flotte"
            echo "  help - Afficher cette aide"
            echo ""
            echo "Catégories : ${!USER_CATEGORIES[*]}"
            ;;
        *)
            log_action "ERREUR : Action inconnue : $action"
            exit 1
            ;;
    esac
    
    log_action "=== Gestion d'utilisateurs terminée ==="
}

# Exécuter la fonction principale
main "$@"

Tâches Communes de Gestion d'Utilisateurs

Affichage des Informations Utilisateur

#!/bin/bash

# Afficher des informations complètes sur l'utilisateur
show_user_info() {
    local username="$1"
    
    if ! id "$username" &>/dev/null; then
        echo "L'utilisateur '$username' n'existe pas"
        return 1
    fi
    
    echo "=== Informations Utilisateur : $username ==="
    
    # Informations utilisateur de base
    echo "Informations ID Utilisateur :"
    id "$username"
    
    # Appartenance aux groupes
    echo -e "\nAppartenance aux Groupes :"
    groups "$username"
    
    # Informations répertoire home
    local home_dir=$(dscl . -read "/Users/$username" NFSHomeDirectory | cut -d: -f2 | xargs)
    echo -e "\nRépertoire Home : $home_dir"
    if [[ -d "$home_dir" ]]; then
        echo "Taille du répertoire home : $(du -sh "$home_dir" | cut -f1)"
    fi
    
    # Shell de connexion
    local shell=$(dscl . -read "/Users/$username" UserShell | cut -d: -f2 | xargs)
    echo -e "\nShell de Connexion : $shell"
    
    # Statut du compte
    echo -e "\nStatut du Compte :"
    if dscl . -read "/Users/$username" AuthenticationAuthority &>/dev/null; then
        echo "Compte : Activé"
    else
        echo "Compte : Désactivé"
    fi
    
    # Statut administrateur
    if dseditgroup -o checkmember -m "$username" admin &>/dev/null; then
        echo "Privilèges Administrateur : Oui"
    else
        echo "Privilèges Administrateur : Non"
    fi
    
    # Dernière connexion
    echo -e "\nDernière Connexion :"
    last -1 "$username" | head -1
}

# Utilisation
show_user_info "daniel"

Gestion des Mots de Passe

#!/bin/bash

# Gestion complète des mots de passe
manage_user_password() {
    local username="$1"
    local action="$2"
    local new_password="$3"
    
    if ! id "$username" &>/dev/null; then
        echo "L'utilisateur '$username' n'existe pas"
        return 1
    fi
    
    export PATH=/usr/bin:/bin:/usr/sbin:/sbin
    
    case "$action" in
        "change")
            if [[ -z "$new_password" ]]; then
                echo "Nouveau mot de passe requis"
                return 1
            fi
            
            if ! validate_password_strength "$new_password"; then
                return 1
            fi
            
            if sysadminctl -resetPasswordFor "$username" -newPassword "$new_password"; then
                echo "Mot de passe changé avec succès pour l'utilisateur : $username"
                
                # Forcer le changement de mot de passe à la prochaine connexion (optionnel)
                # pwpolicy -u "$username" -setpolicy "newPasswordRequired=1"
            else
                echo "Échec du changement de mot de passe"
                return 1
            fi
            ;;
        "expire")
            echo "Expiration du mot de passe pour l'utilisateur : $username"
            if pwpolicy -u "$username" -setpolicy "newPasswordRequired=1"; then
                echo "Mot de passe expiré - l'utilisateur doit le changer à la prochaine connexion"
            else
                echo "Échec de l'expiration du mot de passe"
                return 1
            fi
            ;;
        "unlock")
            echo "Déverrouillage du compte pour l'utilisateur : $username"
            if pwpolicy -u "$username" -setpolicy "isDisabled=0"; then
                echo "Compte déverrouillé avec succès"
            else
                echo "Échec du déverrouillage du compte"
                return 1
            fi
            ;;
        *)
            echo "Action de mot de passe inconnue : $action"
            echo "Actions disponibles : change, expire, unlock"
            return 1
            ;;
    esac
}

# Utilisation
manage_user_password "daniel" "change" "NewSecurePassword123!"

Gestion des Groupes

#!/bin/bash

# Gestion des groupes d'utilisateurs
manage_user_groups() {
    local username="$1"
    local action="$2"
    local group_name="$3"
    
    if ! id "$username" &>/dev/null; then
        echo "L'utilisateur '$username' n'existe pas"
        return 1
    fi
    
    case "$action" in
        "add")
            echo "Ajout de l'utilisateur '$username' au groupe '$group_name'"
            if dseditgroup -o edit -a "$username" -t user "$group_name"; then
                echo "✓ Utilisateur ajouté au groupe avec succès"
            else
                echo "✗ Échec de l'ajout de l'utilisateur au groupe"
                return 1
            fi
            ;;
        "remove")
            echo "Suppression de l'utilisateur '$username' du groupe '$group_name'"
            if dseditgroup -o edit -d "$username" -t user "$group_name"; then
                echo "✓ Utilisateur supprimé du groupe avec succès"
            else
                echo "✗ Échec de la suppression de l'utilisateur du groupe"
                return 1
            fi
            ;;
        "list")
            echo "Groupes pour l'utilisateur '$username' :"
            groups "$username"
            ;;
        *)
            echo "Action de groupe inconnue : $action"
            echo "Actions disponibles : add, remove, list"
            return 1
            ;;
    esac
}

# Utilisation
manage_user_groups "daniel" "add" "developers"
manage_user_groups "daniel" "list"

Notes Importantes

  • Privilèges administrateur requis pour la création et modification d'utilisateurs
  • Politiques de mots de passe doivent imposer des mots de passe forts pour la sécurité
  • Validation utilisateur - Toujours vérifier les entrées avant de créer des comptes
  • Permissions du répertoire home - Assurer la propriété et permissions appropriées
  • Sauvegarde des données utilisateur avant les opérations de suppression
  • Tester les scripts sur des comptes individuels avant le déploiement en flotte
  • Surveiller les activités utilisateur pour la conformité de sécurité

Suppression de Comptes Utilisateur et Gestion du Cycle de Vie sur macOS

Gérez le cycle de vie des comptes utilisateur et les processus de suppression sécurisée sur vos appareils Roundfleet avec une gestion complète des utilisateurs, des politiques de rétention des données et des procédures de départ d'entreprise. Ce tutoriel couvre la suppression sécurisée des utilisateurs, l'archivage des données et la gestion du cycle de vie conforme aux réglementations.

Comprendre la Suppression de Comptes Utilisateur

La suppression de comptes utilisateur sur macOS implique plusieurs composants et considérations de sécurité :

  • Suppression de Compte - Supprimer le compte utilisateur des bases de données système
  • Gestion des Données - Traiter les répertoires personnels et fichiers associés
  • Jetons de Sécurité - Gérer les exigences de jeton sécurisé pour la suppression
  • Conformité d'Entreprise - Respecter les exigences de rétention des données et de confidentialité

Considérations d'Entreprise

Une suppression appropriée de compte utilisateur nécessite une planification d'entreprise :

  • Politiques de Rétention des Données - Conformité aux exigences légales et réglementaires
  • Protocoles de Sécurité - Assurer la suppression complète des données et la révocation d'accès
  • Exigences d'Audit - Maintenir les journaux de suppression pour le suivi de conformité
  • Procédures de Récupération - Capacités de sauvegarde et récupération avant suppression
  • Automatisation des Processus - Procédures de départ rationalisées pour les employés qui partent

Suppression de Base de Comptes Utilisateur

Prérequis et Exigences de Sécurité

#!/bin/bash

# Vérifier les prérequis pour la suppression d'utilisateur
check_deletion_prerequisites() {
    echo "=== Vérification des Prérequis de Suppression d'Utilisateur ==="
    
    # Vérifier si exécuté avec privilèges administrateur
    if [[ $EUID -ne 0 ]]; then
        echo "⚠️ Avertissement : Ce script nécessite des privilèges administrateur"
        echo "Exécuter avec : sudo $0"
    else
        echo "✓ Privilèges administrateur confirmés"
    fi
    
    # Vérifier l'accès disque complet de l'app Service
    echo ""
    echo "--- Vérification Accès Disque Complet ---"
    local tcc_db="/Library/Application Support/com.apple.TCC/TCC.db"
    if [[ -r "$tcc_db" ]]; then
        echo "✓ Base de données TCC accessible - Accès disque complet probablement accordé"
    else
        echo "⚠️ Avertissement : Base de données TCC non accessible"
        echo "Assurez-vous que l'app Service a l'Accès Disque Complet dans Préférences Système"
    fi
    
    # Vérifier les détenteurs de jeton sécurisé disponibles
    echo ""
    echo "--- Analyse Jeton Sécurisé ---"
    local secure_token_users=$(sysadminctl -secureTokenStatus 2>/dev/null | grep "Enabled" | wc -l | tr -d ' ')
    echo "Détenteurs de jeton sécurisé trouvés : $secure_token_users"
    
    if [[ $secure_token_users -lt 2 ]]; then
        echo "⚠️ Avertissement : Moins de 2 détenteurs de jeton sécurisé détectés"
        echo "Impossible de supprimer l'unique détenteur de jeton sécurisé"
        echo "Ajouter un autre utilisateur admin avec jeton sécurisé avant suppression"
    else
        echo "✓ Plusieurs détenteurs de jeton sécurisé disponibles"
    fi
}

# Usage
check_deletion_prerequisites

Suppression Sécurisée de Compte Utilisateur

#!/bin/bash

# Supprimer un compte utilisateur en toute sécurité avec validation
delete_user_account() {
    local username="$1"
    local method="${2:-sysadminctl}"  # sysadminctl ou dscl
    local backup_data="${3:-true}"
    
    if [[ -z "$username" ]]; then
        echo "Usage : delete_user_account <nom_utilisateur> [méthode] [sauvegarder_données]"
        echo "Méthodes : sysadminctl (par défaut), dscl"
        echo "Sauvegarder données : true (par défaut), false"
        return 1
    fi
    
    echo "=== Suppression Sécurisée de Compte Utilisateur ==="
    echo "Utilisateur cible : $username"
    echo "Méthode de suppression : $method"
    echo "Sauvegarder données : $backup_data"
    echo ""
    
    # Valider que l'utilisateur existe
    if ! id "$username" >/dev/null 2>&1; then
        echo "Erreur : L'utilisateur '$username' n'existe pas"
        return 1
    fi
    
    # Vérifier si l'utilisateur est actuellement connecté
    local logged_in_users=$(who | awk '{print $1}' | sort -u)
    if echo "$logged_in_users" | grep -q "^$username$"; then
        echo "⚠️ Avertissement : L'utilisateur '$username' est actuellement connecté"
        echo "Forcer la déconnexion ou attendre que l'utilisateur se déconnecte avant suppression"
        return 1
    fi
    
    # Vérifier le statut du jeton sécurisé
    local token_status=$(sysadminctl -secureTokenStatus "$username" 2>/dev/null | grep "Enabled")
    if [[ -n "$token_status" ]]; then
        echo "L'utilisateur '$username' a un jeton sécurisé"
        
        # Compter le total des détenteurs de jeton sécurisé
        local total_tokens=$(sysadminctl -secureTokenStatus 2>/dev/null | grep "Enabled" | wc -l | tr -d ' ')
        if [[ $total_tokens -eq 1 ]]; then
            echo "Erreur : Impossible de supprimer l'unique détenteur de jeton sécurisé"
            echo "Ajouter d'abord un autre utilisateur admin avec jeton sécurisé"
            return 1
        fi
    fi
    
    # Sauvegarder les données utilisateur si demandé
    if [[ "$backup_data" == "true" ]]; then
        echo "Création de sauvegarde des données utilisateur..."
        backup_user_data "$username"
    fi
    
    # Effectuer la suppression basée sur la méthode
    echo ""
    echo "--- Suppression du Compte Utilisateur ---"
    case "$method" in
        "sysadminctl")
            delete_user_sysadminctl "$username"
            ;;
        "dscl")
            delete_user_dscl "$username"
            ;;
        *)
            echo "Erreur : Méthode de suppression inconnue : $method"
            return 1
            ;;
    esac
}

# Supprimer utilisateur avec sysadminctl (macOS 10.13+)
delete_user_sysadminctl() {
    local username="$1"
    
    echo "Utilisation de sysadminctl pour supprimer l'utilisateur : $username"
    
    if sysadminctl -deleteUser "$username" 2>/dev/null; then
        echo "✓ Compte utilisateur '$username' supprimé avec succès avec sysadminctl"
        return 0
    else
        echo "✗ Échec de suppression de l'utilisateur '$username' avec sysadminctl"
        return 1
    fi
}

# Supprimer utilisateur avec dscl (méthode héritée)
delete_user_dscl() {
    local username="$1"
    
    echo "Utilisation de dscl pour supprimer l'utilisateur : $username"
    
    if dscl . delete "/Users/$username" 2>/dev/null; then
        echo "✓ Compte utilisateur '$username' supprimé avec succès avec dscl"
        return 0
    else
        echo "✗ Échec de suppression de l'utilisateur '$username' avec dscl"
        return 1
    fi
}

# Exemple d'utilisation (commenté pour sécurité)
# delete_user_account "employe_partant" "sysadminctl" "true"

Gestion des Données et Répertoires Utilisateur

#!/bin/bash

# Gestion complète des données utilisateur
manage_user_data() {
    local username="$1"
    local action="${2:-archive}"  # archive, delete, preserve
    local backup_location="${3:-/var/backups/user_data}"
    
    if [[ -z "$username" ]]; then
        echo "Usage : manage_user_data <nom_utilisateur> [action] [emplacement_sauvegarde]"
        echo "Actions : archive (par défaut), delete, preserve"
        return 1
    fi
    
    echo "=== Gestion des Données Utilisateur ==="
    echo "Nom d'utilisateur : $username"
    echo "Action : $action"
    echo "Emplacement de sauvegarde : $backup_location"
    echo ""
    
    local user_home="/Users/$username"
    
    # Vérifier si le répertoire personnel utilisateur existe
    if [[ ! -d "$user_home" ]]; then
        echo "Répertoire personnel utilisateur non trouvé : $user_home"
        return 1
    fi
    
    # Obtenir la taille du répertoire pour rapport
    local dir_size=$(du -sh "$user_home" 2>/dev/null | awk '{print $1}')
    echo "Taille du répertoire personnel utilisateur : $dir_size"
    
    case "$action" in
        "archive")
            archive_user_data "$username" "$backup_location"
            ;;
        "delete")
            delete_user_data "$username"
            ;;
        "preserve")
            preserve_user_data "$username"
            ;;
        *)
            echo "Erreur : Action inconnue : $action"
            return 1
            ;;
    esac
}

# Archiver les données utilisateur avant suppression
archive_user_data() {
    local username="$1"
    local backup_location="$2"
    
    echo "--- Archivage des Données Utilisateur ---"
    
    # Créer le répertoire de sauvegarde s'il n'existe pas
    mkdir -p "$backup_location"
    
    local timestamp=$(date +%Y%m%d_%H%M%S)
    local archive_name="${username}_backup_${timestamp}.tar.gz"
    local archive_path="$backup_location/$archive_name"
    
    echo "Création de l'archive : $archive_path"
    
    # Créer une archive compressée du répertoire personnel utilisateur
    if tar -czf "$archive_path" -C "/Users" "$username" 2>/dev/null; then
        echo "✓ Données utilisateur archivées avec succès"
        
        # Créer un fichier de métadonnées
        local metadata_file="$backup_location/${username}_metadata_${timestamp}.json"
        cat > "$metadata_file" << EOF
{
    "backup_metadata": {
        "username": "$username",
        "backup_date": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
        "archive_file": "$archive_name",
        "archive_size": "$(du -sh "$archive_path" | awk '{print $1}')",
        "original_path": "/Users/$username",
        "backup_location": "$backup_location",
        "hostname": "$(hostname)",
        "created_by": "$(whoami)"
    }
}
EOF
        
        echo "✓ Fichier de métadonnées créé : $metadata_file"
        echo "Détails de l'archive :"
        echo "  Fichier : $archive_path"
        echo "  Taille : $(du -sh "$archive_path" | awk '{print $1}')"
        
        return 0
    else
        echo "✗ Échec de création de l'archive"
        return 1
    fi
}

# Supprimer les données et répertoires utilisateur
delete_user_data() {
    local username="$1"
    local user_home="/Users/$username"
    
    echo "--- Suppression des Données Utilisateur ---"
    echo "⚠️ AVERTISSEMENT : Ceci supprimera définitivement toutes les données utilisateur"
    echo "Répertoire cible : $user_home"
    
    # Vérification de sécurité - ne pas supprimer les répertoires système
    case "$username" in
        "root"|"admin"|"administrator"|"Guest"|"Shared")
            echo "Erreur : Impossible de supprimer les données utilisateur système : $username"
            return 1
            ;;
    esac
    
    if [[ "$user_home" == "/Users/"* && ${#username} -gt 2 ]]; then
        echo "Suppression du répertoire personnel utilisateur..."
        if rm -rf "$user_home" 2>/dev/null; then
            echo "✓ Données utilisateur supprimées avec succès : $user_home"
            return 0
        else
            echo "✗ Échec de suppression des données utilisateur : $user_home"
            return 1
        fi
    else
        echo "Erreur : Chemin de répertoire personnel invalide : $user_home"
        return 1
    fi
}

# Préserver les données utilisateur avec changement de propriété
preserve_user_data() {
    local username="$1"
    local user_home="/Users/$username"
    local preserved_name="${username}_preserved_$(date +%Y%m%d)"
    local preserved_path="/Users/$preserved_name"
    
    echo "--- Préservation des Données Utilisateur ---"
    echo "Renommage du répertoire utilisateur pour préservation"
    echo "De : $user_home"
    echo "Vers : $preserved_path"
    
    if mv "$user_home" "$preserved_path" 2>/dev/null; then
        # Changer la propriété vers l'utilisateur admin
        chown -R root:admin "$preserved_path" 2>/dev/null
        chmod -R 755 "$preserved_path" 2>/dev/null
        
        echo "✓ Données utilisateur préservées à : $preserved_path"
        echo "✓ Propriété changée vers root:admin"
        return 0
    else
        echo "✗ Échec de préservation des données utilisateur"
        return 1
    fi
}

# Exemple d'utilisation
# manage_user_data "employe_partant" "archive" "/var/backups/user_data"

Système de Gestion du Cycle de Vie d'Entreprise

#!/bin/bash

# Outil de Suppression de Comptes Utilisateur et Gestion du Cycle de Vie Roundfleet
# Départ d'entreprise complet, gestion des données et conformité

# Configuration
SCRIPT_VERSION="1.0.0"
LOG_FILE="/var/log/roundfleet_user_lifecycle.log"
REPORT_DIR="/etc/roundfleet/reports/users"
CONFIG_DIR="/etc/roundfleet/user_management"
POLICY_DIR="/etc/roundfleet/policies/users"
BACKUP_DIR="/var/backups/roundfleet/users"
COMPLIANCE_DIR="/etc/roundfleet/compliance/users"

# Créer les répertoires s'ils n'existent pas
mkdir -p "$REPORT_DIR" "$CONFIG_DIR" "$POLICY_DIR" "$BACKUP_DIR" "$COMPLIANCE_DIR"

# Politiques de cycle de vie utilisateur
declare -A LIFECYCLE_POLICIES=(
    ["immediate_deletion"]="delete_account,delete_data,no_backup,audit_log"
    ["secure_archival"]="backup_data,delete_account,delete_data,compliance_report"
    ["data_preservation"]="backup_data,preserve_home,delete_account,extended_audit"
    ["legal_hold"]="preserve_all,disable_account,legal_compliance,no_deletion"
    ["healthcare_hipaa"]="encrypted_backup,secure_deletion,hipaa_compliance,audit_trail"
    ["financial_compliance"]="full_backup,sox_compliance,retention_policy,secure_deletion"
    ["education_ferpa"]="student_data_protection,ferpa_compliance,selective_backup,audit_log"
    ["government_classified"]="classified_data_handling,security_clearance_check,secure_deletion,audit_trail"
    ["contractor_offboarding"]="project_data_separation,limited_backup,quick_deletion,access_revocation"
    ["temporary_disable"]="disable_only,preserve_all,no_deletion,reactivation_ready"
)

# Périodes de rétention des données (en jours)
declare -A RETENTION_PERIODS=(
    ["immediate"]="0"
    ["short_term"]="30"
    ["medium_term"]="90"
    ["long_term"]="365"
    ["legal_hold"]="indefinite"
    ["compliance_minimum"]="2555"  # 7 ans
)

# Cadres de conformité
declare -A COMPLIANCE_FRAMEWORKS=(
    ["hipaa"]="healthcare_data_protection,encrypted_storage,audit_logs,secure_deletion"
    ["sox"]="financial_records_retention,change_management,access_controls,audit_trail"
    ["ferpa"]="student_privacy,educational_records,consent_management,access_restrictions"
    ["gdpr"]="data_minimization,consent_withdrawal,right_to_erasure,data_portability"
    ["pci_dss"]="payment_data_protection,secure_deletion,access_monitoring,compliance_reporting"
)

# Fonction de journalisation
log_action() {
    local message="$1"
    local severity="${2:-INFO}"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo "[$timestamp] [$severity] $message" | tee -a "$LOG_FILE"
}

# Suppression de compte utilisateur d'entreprise avec fonctionnalités avancées
enterprise_user_deletion() {
    local username="$1"
    local policy="${2:-secure_archival}"
    local compliance_framework="${3:-}"
    local retention_period="${4:-medium_term}"
    local authorized_by="${5:-$(whoami)}"
    
    log_action "Démarrage du processus de suppression d'utilisateur d'entreprise" "INFO"
    log_action "Nom d'utilisateur : $username, Politique : $policy, Autorisé par : $authorized_by" "INFO"
    
    echo "=== Processus de Suppression d'Utilisateur d'Entreprise ==="
    echo "Nom d'utilisateur : $username"
    echo "Politique : $policy"
    echo "Cadre de Conformité : $compliance_framework"
    echo "Période de Rétention : $retention_period"
    echo "Autorisé Par : $authorized_by"
    echo "ID de Processus : $(uuidgen)"
    echo ""
    
    # Valider que l'utilisateur existe
    if ! id "$username" >/dev/null 2>&1; then
        log_action "ERREUR : L'utilisateur '$username' n'existe pas" "ERROR"
        return 1
    fi
    
    # Validation pré-suppression
    if ! pre_deletion_validation "$username"; then
        log_action "ERREUR : Validation pré-suppression échouée pour utilisateur : $username" "ERROR"
        return 1
    fi
    
    # Appliquer le processus de suppression basé sur politique
    apply_deletion_policy "$username" "$policy" "$compliance_framework" "$retention_period" "$authorized_by"
    
    # Générer le rapport de conformité
    generate_deletion_compliance_report "$username" "$policy" "$compliance_framework" "$authorized_by"
    
    log_action "Processus de suppression d'utilisateur d'entreprise terminé pour utilisateur : $username" "INFO"
}

# Validation pré-suppression et vérifications de sécurité
pre_deletion_validation() {
    local username="$1"
    
    echo "--- Validation Pré-Suppression ---"
    
    # Vérifier si l'utilisateur est un utilisateur système
    local user_id=$(id -u "$username" 2>/dev/null)
    if [[ $user_id -lt 500 ]]; then
        echo "✗ Impossible de supprimer l'utilisateur système (UID < 500) : $username"
        return 1
    fi
    
    # Vérifier si l'utilisateur est actuellement connecté
    if who | grep -q "^$username "; then
        echo "✗ L'utilisateur est actuellement connecté : $username"
        log_action "Suppression bloquée : L'utilisateur $username est actuellement connecté" "WARNING"
        return 1
    fi
    
    # Vérifier les exigences de jeton sécurisé
    local has_secure_token=$(sysadminctl -secureTokenStatus "$username" 2>/dev/null | grep -c "Enabled")
    if [[ $has_secure_token -eq 1 ]]; then
        local total_secure_tokens=$(sysadminctl -secureTokenStatus 2>/dev/null | grep -c "Enabled")
        if [[ $total_secure_tokens -eq 1 ]]; then
            echo "✗ Impossible de supprimer l'unique détenteur de jeton sécurisé : $username"
            log_action "Suppression bloquée : $username est l'unique détenteur de jeton sécurisé" "ERROR"
            return 1
        fi
    fi
    
    # Vérifier les processus actifs appartenant à l'utilisateur
    local user_processes=$(ps aux | awk -v user="$username" '$1 == user {print $2}' | wc -l | tr -d ' ')
    if [[ $user_processes -gt 0 ]]; then
        echo "⚠️ Avertissement : L'utilisateur a $user_processes processus actifs"
        echo "Arrêt des processus utilisateur..."
        pkill -u "$username" 2>/dev/null
        sleep 2
    fi
    
    # Vérifier la taille du répertoire personnel pour planification de sauvegarde
    local home_dir="/Users/$username"
    if [[ -d "$home_dir" ]]; then
        local dir_size=$(du -sm "$home_dir" 2>/dev/null | awk '{print $1}')
        echo "✓ Taille du répertoire personnel : ${dir_size}MB"
        
        # Vérifier l'espace disque disponible pour sauvegarde
        local available_space=$(df -m "$BACKUP_DIR" | tail -1 | awk '{print $4}')
        if [[ $dir_size -gt $available_space ]]; then
            echo "⚠️ Avertissement : Espace insuffisant pour sauvegarde"
            echo "Requis : ${dir_size}MB, Disponible : ${available_space}MB"
        fi
    fi
    
    echo "✓ Validation pré-suppression terminée"
    return 0
}

# Appliquer la politique de suppression
apply_deletion_policy() {
    local username="$1"
    local policy="$2"
    local compliance_framework="$3"
    local retention_period="$4"
    local authorized_by="$5"
    
    echo "--- Application de la Politique de Suppression : $policy ---"
    
    # Obtenir les actions de politique
    local policy_actions="${LIFECYCLE_POLICIES[$policy]}"
    if [[ -z "$policy_actions" ]]; then
        log_action "ERREUR : Politique de suppression inconnue : $policy" "ERROR"
        return 1
    fi
    
    echo "Actions de politique : $policy_actions"
    
    # Exécuter les actions de politique
    IFS=',' read -ra ACTIONS <<< "$policy_actions"
    for action in "${ACTIONS[@]}"; do
        case "$action" in
            "backup_data")
                echo "Exécution : Sauvegarde des données utilisateur"
                backup_user_data_enterprise "$username" "$compliance_framework"
                ;;
            "delete_account")
                echo "Exécution : Suppression du compte utilisateur"
                delete_user_account_enterprise "$username"
                ;;
            "delete_data")
                echo "Exécution : Suppression des données utilisateur"
                delete_user_data_secure "$username"
                ;;
            "preserve_home")
                echo "Exécution : Préservation du répertoire personnel"
                preserve_user_data "$username"
                ;;
            "disable_account")
                echo "Exécution : Désactivation du compte utilisateur"
                disable_user_account "$username"
                ;;
            "audit_log")
                echo "Exécution : Création du journal d'audit"
                create_audit_log "$username" "$policy" "$authorized_by"
                ;;
            "compliance_report")
                echo "Exécution : Génération du rapport de conformité"
                # Sera traité séparément
                ;;
            *)
                echo "Action inconnue : $action"
                ;;
        esac
    done
}

# Sauvegarde d'entreprise avec chiffrement et conformité
backup_user_data_enterprise() {
    local username="$1"
    local compliance_framework="$2"
    
    echo "--- Sauvegarde de Données d'Entreprise ---"
    
    local timestamp=$(date +%Y%m%d_%H%M%S)
    local backup_name="${username}_enterprise_backup_${timestamp}"
    local backup_path="$BACKUP_DIR/$backup_name"
    
    # Créer la sauvegarde avec métadonnées
    mkdir -p "$backup_path"
    
    # Copier les données utilisateur
    local user_home="/Users/$username"
    if [[ -d "$user_home" ]]; then
        echo "Sauvegarde du répertoire personnel utilisateur..."
        tar -czf "$backup_path/home_directory.tar.gz" -C "/Users" "$username" 2>/dev/null
    fi
    
    # Sauvegarder les informations de compte utilisateur
    echo "Sauvegarde des métadonnées de compte..."
    dscl . read "/Users/$username" > "$backup_path/account_metadata.txt" 2>/dev/null
    
    # Créer le manifeste de sauvegarde
    cat > "$backup_path/backup_manifest.json" << EOF
{
    "backup_manifest": {
        "username": "$username",
        "backup_date": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
        "backup_type": "enterprise_offboarding",
        "compliance_framework": "$compliance_framework",
        "backup_location": "$backup_path",
        "files_included": [
            "home_directory.tar.gz",
            "account_metadata.txt",
            "backup_manifest.json"
        ],
        "backup_size": "$(du -sh "$backup_path" | awk '{print $1}')",
        "hostname": "$(hostname)",
        "authorized_by": "$(whoami)",
        "backup_integrity": "$(find "$backup_path" -type f -exec md5 {} \; | md5)"
    }
}
EOF
    
    # Appliquer les protections spécifiques à la conformité
    if [[ -n "$compliance_framework" ]]; then
        apply_compliance_protections "$backup_path" "$compliance_framework"
    fi
    
    echo "✓ Sauvegarde d'entreprise terminée : $backup_path"
    log_action "Sauvegarde d'entreprise créée pour utilisateur $username à $backup_path" "INFO"
}

# Suppression sécurisée avec exigences de conformité
delete_user_data_secure() {
    local username="$1"
    local user_home="/Users/$username"
    
    echo "--- Suppression Sécurisée des Données ---"
    
    if [[ -d "$user_home" ]]; then
        echo "Exécution de la suppression sécurisée des données utilisateur..."
        
        # Suppression sécurisée multi-passes (standard DoD 5220.22-M)
        if command -v gshred >/dev/null 2>&1; then
            echo "Utilisation de gshred pour suppression sécurisée..."
            find "$user_home" -type f -exec gshred -vfz -n 3 {} \; 2>/dev/null
        elif command -v shred >/dev/null 2>&1; then
            echo "Utilisation de shred pour suppression sécurisée..."
            find "$user_home" -type f -exec shred -vfz -n 3 {} \; 2>/dev/null
        else
            echo "Outils de suppression sécurisée non disponibles, utilisation suppression standard..."
        fi
        
        # Supprimer la structure de répertoire
        rm -rf "$user_home" 2>/dev/null
        
        echo "✓ Suppression sécurisée terminée"
        log_action "Suppression sécurisée terminée pour données utilisateur : $user_home" "INFO"
    else
        echo "Aucun répertoire personnel utilisateur trouvé : $user_home"
    fi
}

# Désactiver le compte utilisateur au lieu de la suppression
disable_user_account() {
    local username="$1"
    
    echo "--- Désactivation du Compte Utilisateur ---"
    
    # Désactiver le compte avec dscl
    if dscl . create "/Users/$username" AuthenticationAuthority ";DisabledUser;" 2>/dev/null; then
        echo "✓ Compte utilisateur désactivé : $username"
        log_action "Compte utilisateur désactivé : $username" "INFO"
    else
        echo "✗ Échec de désactivation du compte utilisateur : $username"
        log_action "Échec de désactivation du compte utilisateur : $username" "ERROR"
    fi
    
    # Définir le shell de compte à /usr/bin/false
    dscl . create "/Users/$username" UserShell "/usr/bin/false" 2>/dev/null
    
    # Verrouiller le répertoire personnel
    local user_home="/Users/$username"
    if [[ -d "$user_home" ]]; then
        chmod 000 "$user_home" 2>/dev/null
        echo "✓ Accès au répertoire personnel révoqué"
    fi
}

# Générer un rapport de conformité complet
generate_deletion_compliance_report() {
    local username="$1"
    local policy="$2"
    local compliance_framework="$3"
    local authorized_by="$4"
    
    local report_file="$REPORT_DIR/user_deletion_report_${username}_$(date +%Y%m%d_%H%M%S).json"
    
    cat > "$report_file" << EOF
{
    "user_deletion_compliance_report": {
        "report_metadata": {
            "report_id": "$(uuidgen)",
            "generated_date": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
            "report_type": "user_account_deletion",
            "compliance_framework": "$compliance_framework",
            "hostname": "$(hostname)",
            "script_version": "$SCRIPT_VERSION"
        },
        "user_information": {
            "username": "$username",
            "deletion_policy": "$policy",
            "authorized_by": "$authorized_by",
            "deletion_timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
        },
        "compliance_details": {
            "framework": "$compliance_framework",
            "data_retention_requirements": "$(echo "${RETENTION_PERIODS[medium_term]}" | sed 's/indefinite/Rétention légale - rétention indéfinie/')",
            "secure_deletion_method": "Standard DoD 5220.22-M",
            "backup_location": "$BACKUP_DIR",
            "audit_trail": "$LOG_FILE"
        },
        "system_information": {
            "os_version": "$(sw_vers -productVersion)",
            "hardware_model": "$(system_profiler SPHardwareDataType | grep 'Model Identifier' | awk '{print $3}')",
            "secure_token_holders": $(sysadminctl -secureTokenStatus 2>/dev/null | grep -c "Enabled")
        }
    }
}
EOF
    
    echo "Rapport de conformité généré : $report_file"
    log_action "Rapport de conformité généré : $report_file" "INFO"
}

# Opérations de gestion d'utilisateurs de flotte
manage_fleet_users() {
    local operation="$1"
    local user_list="$2"
    local policy="${3:-secure_archival}"
    local compliance_framework="${4:-}"
    
    echo "=== Gestion d'Utilisateurs de Flotte ==="
    echo "Opération : $operation"
    echo "Politique : $policy"
    echo "Cadre de Conformité : $compliance_framework"
    echo ""
    
    case "$operation" in
        "bulk_delete")
            echo "Traitement de suppression d'utilisateurs en lot..."
            IFS=',' read -ra USERS <<< "$user_list"
            for username in "${USERS[@]}"; do
                echo "Traitement de l'utilisateur : $username"
                enterprise_user_deletion "$username" "$policy" "$compliance_framework"
                echo ""
            done
            ;;
        "audit_all")
            echo "Audit de tous les comptes utilisateur..."
            audit_all_users
            ;;
        "compliance_check")
            echo "Exécution de vérification de conformité..."
            compliance_check_users "$compliance_framework"
            ;;
        *)
            echo "Opération inconnue : $operation"
            return 1
            ;;
    esac
}

# Fonction d'exécution principale
main() {
    local action="${1:-help}"
    local param1="${2:-}"
    local param2="${3:-}"
    local param3="${4:-}"
    local param4="${5:-}"
    local param5="${6:-}"
    
    log_action "=== Gestion du Cycle de Vie Utilisateur Roundfleet Démarrée ===" "INFO"
    log_action "Action : $action" "INFO"
    
    case "$action" in
        "delete")
            if [[ -z "$param1" ]]; then
                echo "Usage : $0 delete <nom_utilisateur> [politique] [cadre_conformité] [période_rétention] [autorisé_par]"
                echo "Politiques : ${!LIFECYCLE_POLICIES[*]}"
                echo "Conformité : ${!COMPLIANCE_FRAMEWORKS[*]}"
                echo "Rétention : ${!RETENTION_PERIODS[*]}"
                exit 1
            fi
            enterprise_user_deletion "$param1" "$param2" "$param3" "$param4" "$param5"
            ;;
        "backup")
            if [[ -z "$param1" ]]; then
                echo "Usage : $0 backup <nom_utilisateur> [cadre_conformité]"
                exit 1
            fi
            backup_user_data_enterprise "$param1" "$param2"
            ;;
        "disable")
            if [[ -z "$param1" ]]; then
                echo "Usage : $0 disable <nom_utilisateur>"
                exit 1
            fi
            disable_user_account "$param1"
            ;;
        "fleet")
            if [[ -z "$param1" || -z "$param2" ]]; then
                echo "Usage : $0 fleet <opération> <liste_utilisateurs> [politique] [cadre_conformité]"
                echo "Opérations : bulk_delete, audit_all, compliance_check"
                exit 1
            fi
            manage_fleet_users "$param1" "$param2" "$param3" "$param4"
            ;;
        "validate")
            if [[ -z "$param1" ]]; then
                echo "Usage : $0 validate <nom_utilisateur>"
                exit 1
            fi
            pre_deletion_validation "$param1"
            ;;
        "prereq")
            check_deletion_prerequisites
            ;;
        "help")
            echo "Usage : $0 [action] [options...]"
            echo "Actions :"
            echo "  delete <nom_utilisateur> [politique] [conformité] [rétention] [autorisé_par] - Supprimer utilisateur avec politiques d'entreprise"
            echo "  backup <nom_utilisateur> [conformité] - Sauvegarder données utilisateur"
            echo "  disable <nom_utilisateur> - Désactiver compte utilisateur"
            echo "  fleet <opération> <liste_utilisateurs> [politique] [conformité] - Opérations utilisateurs de flotte"
            echo "  validate <nom_utilisateur> - Valider prérequis suppression"
            echo "  prereq - Vérifier prérequis système"
            echo "  help - Afficher cette aide"
            echo ""
            echo "Politiques : ${!LIFECYCLE_POLICIES[*]}"
            echo "Conformité : ${!COMPLIANCE_FRAMEWORKS[*]}"
            echo "Rétention : ${!RETENTION_PERIODS[*]}"
            ;;
        *)
            log_action "ERREUR : Action inconnue : $action" "ERROR"
            echo "Utilisez '$0 help' pour les informations d'utilisation"
            exit 1
            ;;
    esac
    
    log_action "=== Gestion du cycle de vie utilisateur terminée ===" "INFO"
}

# Exécuter la fonction principale
main "$@"

Considérations de Sécurité Importantes

Exigences de Jeton Sécurisé

#!/bin/bash

# Gérer les exigences de jeton sécurisé pour suppression d'utilisateur
manage_secure_tokens() {
    echo "=== Gestion des Jetons Sécurisés ==="
    
    # Lister tous les détenteurs de jeton sécurisé
    echo "Détenteurs de jeton sécurisé actuels :"
    sysadminctl -secureTokenStatus 2>/dev/null | grep -E "(Username|Enabled)"
    
    echo ""
    echo "--- Directives Jeton Sécurisé ---"
    echo "1. Impossible de supprimer l'unique détenteur de jeton sécurisé"
    echo "2. Doit avoir au moins un admin avec jeton sécurisé"
    echo "3. Accorder jeton sécurisé avant tentative de suppression"
    echo "4. Jeton sécurisé requis pour FileVault et certaines opérations"
}

# Accorder jeton sécurisé à utilisateur admin
grant_secure_token() {
    local admin_user="$1"
    local target_user="$2"
    
    if [[ -z "$admin_user" || -z "$target_user" ]]; then
        echo "Usage : grant_secure_token <utilisateur_admin> <utilisateur_cible>"
        return 1
    fi
    
    echo "Accord de jeton sécurisé à $target_user via $admin_user..."
    sysadminctl -secureTokenOn "$target_user" -password -adminUser "$admin_user"
}

# Usage
manage_secure_tokens

Rétention des Données et Conformité

#!/bin/bash

# Implémenter les politiques de rétention des données
implement_retention_policy() {
    local policy_name="$1"
    local retention_days="${2:-90}"
    
    echo "=== Implémentation de Politique de Rétention des Données ==="
    echo "Politique : $policy_name"
    echo "Période de Rétention : $retention_days jours"
    
    # Trouver les anciennes sauvegardes pour nettoyage
    local old_backups=$(find "$BACKUP_DIR" -type d -mtime +$retention_days 2>/dev/null)
    
    if [[ -n "$old_backups" ]]; then
        echo "Sauvegardes trouvées plus anciennes que $retention_days jours :"
        echo "$old_backups"
        
        # Archiver les anciennes sauvegardes avant suppression (si requis par politique)
        case "$policy_name" in
            "legal_hold")
                echo "Rétention légale active - aucune suppression effectuée"
                ;;
            "compliance_minimum")
                echo "Rétention minimum de conformité - archivage vers stockage long terme"
                ;;
            *)
                echo "Rétention standard - marquage pour suppression"
                ;;
        esac
    else
        echo "Aucune sauvegarde trouvée plus ancienne que $retention_days jours"
    fi
}

# Usage
implement_retention_policy "standard" "90"

Notes Importantes

  • Privilèges Administrateur - La suppression d'utilisateur nécessite des privilèges administrateur et une authentification appropriée
  • Gestion de Jeton Sécurisé - Impossible de supprimer l'unique détenteur de jeton sécurisé ; s'assurer que plusieurs utilisateurs admin existent
  • Accès Disque Complet - L'app Service nécessite la permission Accès Disque Complet dans Préférences Système
  • Sauvegarde des Données - Toujours sauvegarder les données utilisateur avant suppression si requis par les politiques organisationnelles
  • Exigences de Conformité - Différentes industries ont des exigences spécifiques de rétention et suppression des données
  • Pistes d'Audit - Maintenir des journaux complets de toutes les activités de suppression d'utilisateur pour conformité
  • Procédures de Récupération - Tester les procédures de sauvegarde et récupération avant d'implémenter les politiques de suppression

Gestion Entreprise des Fuseaux Horaires sur macOS

Gérez les fuseaux horaires et les paramètres de date/heure dans votre Roundfleet avec automation de niveau entreprise, politiques de conformité géographique et capacités de surveillance complètes.

Comprendre la Gestion Entreprise des Fuseaux Horaires

La gestion des fuseaux horaires en entreprise nécessite plus qu'un simple réglage de l'heure, exigeant :

  • Conformité géographique automatisée avec politiques de fuseaux horaires régionales
  • Synchronisation temporelle centralisée avec serveurs NTP d'entreprise
  • Application de politiques pour les heures d'ouverture et conformité opérationnelle
  • Surveillance en temps réel de la dérive temporelle et du statut de synchronisation
  • Journalisation d'audit pour les exigences de conformité et sécurité
  • Capacités d'intégration avec l'infrastructure et services d'annuaire existants

Processus de Base de Gestion des Fuseaux Horaires

Commandes de Base

  1. Définir Fuseau Horaire - sudo systemsetup -settimezone <timezone>
  2. Lister Fuseaux Horaires - sudo systemsetup -listtimezones
  3. Activer Heure Réseau - /usr/sbin/systemsetup -setusingnetworktime on
  4. Définir Serveur Temps - /usr/sbin/systemsetup -setnetworktimeserver time.apple.com

Exemples de Configuration de Base

# Réglage de fuseau horaire de base
sudo systemsetup -settimezone Pacific/Ponape

# Activer la synchronisation automatique de l'heure
/usr/sbin/systemsetup -setusingnetworktime on -setnetworktimeserver time.apple.com

# Lister les fuseaux horaires disponibles
sudo systemsetup -listtimezones

Système de Gestion des Fuseaux Horaires Entreprise

#!/bin/bash

# Système de Gestion des Fuseaux Horaires Entreprise Roundfleet
# Gestion complète des fuseaux horaires et date/heure avec contrôles entreprise et surveillance

# Configuration
SCRIPT_NAME="Gestionnaire Fuseau Horaire Roundfleet"
VERSION="1.0.0"
LOG_FILE="/var/log/roundfleet_timezone.log"
AUDIT_LOG="/var/log/roundfleet_timezone_audit.log"
CONFIG_DIR="/etc/roundfleet/timezone"
POLICIES_DIR="/etc/roundfleet/timezone/policies"
BACKUP_DIR="/var/backups/timezone"
TEMP_DIR="/tmp/roundfleet_timezone"
TIME_DRIFT_THRESHOLD=30  # secondes
SYNC_CHECK_INTERVAL=300  # 5 minutes
ORGANIZATION_NAME="Roundfleet Entreprise"
DEPLOYMENT_MODE="enterprise"
ENABLE_COMPLIANCE_CHECKING=true
ENABLE_GEOGRAPHIC_POLICIES=true
AUTO_TIME_SYNC=true

# Serveurs de Temps Entreprise (par ordre de priorité)
declare -a ENTERPRISE_TIME_SERVERS=(
    "time.company.com"          # Serveur NTP entreprise principal
    "time2.company.com"         # Serveur NTP entreprise secondaire
    "time.apple.com"            # Serveur temps Apple (fallback)
    "pool.ntp.org"              # Pool NTP public (fallback)
    "time.nist.gov"             # Serveur temps NIST (fallback)
)

# Mapping Politique Géographique
declare -A GEOGRAPHIC_POLICIES=(
    ["US_EAST"]="America/New_York"
    ["US_CENTRAL"]="America/Chicago"
    ["US_MOUNTAIN"]="America/Denver"
    ["US_PACIFIC"]="America/Los_Angeles"
    ["US_ALASKA"]="America/Anchorage"
    ["US_HAWAII"]="Pacific/Honolulu"
    ["EU_LONDON"]="Europe/London"
    ["EU_PARIS"]="Europe/Paris"
    ["EU_BERLIN"]="Europe/Berlin"
    ["EU_ZURICH"]="Europe/Zurich"
    ["ASIA_TOKYO"]="Asia/Tokyo"
    ["ASIA_SINGAPORE"]="Asia/Singapore"
    ["ASIA_HONG_KONG"]="Asia/Hong_Kong"
    ["AUSTRALIA_SYDNEY"]="Australia/Sydney"
)

# Politiques Heures d'Ouverture
declare -A BUSINESS_HOURS_POLICIES=(
    ["standard"]="09:00-17:00"
    ["extended"]="08:00-18:00"
    ["24x7"]="00:00-23:59"
    ["custom"]="configurable"
)

# Exigences de Conformité
declare -A COMPLIANCE_STANDARDS=(
    ["SOX"]="audit_temps_strict"
    ["HIPAA"]="journalisation_synchronisee"
    ["PCI_DSS"]="sync_temps_securise"
    ["ISO27001"]="validation_source_temps"
)

# Créer les répertoires nécessaires
mkdir -p "$CONFIG_DIR"
mkdir -p "$POLICIES_DIR"
mkdir -p "$BACKUP_DIR"
mkdir -p "$TEMP_DIR"
mkdir -p "$(dirname "$LOG_FILE")"
mkdir -p "$(dirname "$AUDIT_LOG")"

# Définir les permissions sécurisées
chmod 755 "$CONFIG_DIR"
chmod 750 "$POLICIES_DIR"
chmod 750 "$BACKUP_DIR"
chmod 700 "$TEMP_DIR"

# Fonctions de journalisation
log_operation() {
    local level="$1"
    local message="$2"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    local admin_user=$(whoami)
    echo "[$timestamp] [$level] [$admin_user] $message" | tee -a "$LOG_FILE"
}

log_security_event() {
    local event_type="$1"
    local details="$2"
    local severity="$3"
    local admin_user=$(whoami)
    
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    local source_ip=$(who am i | awk '{print $5}' | tr -d '()')
    echo "SECURITY|$timestamp|$event_type|$severity|$admin_user|$source_ip|$details" >> "$AUDIT_LOG"
}

# Obtenir les informations actuelles du fuseau horaire
get_current_timezone() {
    local current_tz=$(systemsetup -gettimezone 2>/dev/null | awk -F': ' '{print $2}')
    local current_time=$(date '+%Y-%m-%d %H:%M:%S %Z')
    local utc_time=$(date -u '+%Y-%m-%d %H:%M:%S UTC')
    local time_server=$(systemsetup -getnetworktimeserver 2>/dev/null | awk -F': ' '{print $2}')
    local network_time_status=$(systemsetup -getusingnetworktime 2>/dev/null | awk -F': ' '{print $2}')
    
    echo "=== Informations Fuseau Horaire Actuel ==="
    echo "Fuseau Horaire : $current_tz"
    echo "Heure Locale : $current_time"
    echo "Heure UTC : $utc_time"
    echo "Serveur Temps : $time_server"
    echo "Sync Heure Réseau : $network_time_status"
    echo ""
}

# Lister les fuseaux horaires disponibles avec groupement géographique
list_available_timezones() {
    local filter_region="${1:-all}"
    local format="${2:-grouped}"
    
    echo "=== Fuseaux Horaires Disponibles ==="
    echo "Filtre : $filter_region"
    echo "Format : $format"
    echo ""
    
    if [[ "$format" == "grouped" ]]; then
        # Grouper par région
        echo "Amériques :"
        systemsetup -listtimezones 2>/dev/null | grep "America/" | sort | head -20
        echo ""
        
        echo "Europe :"
        systemsetup -listtimezones 2>/dev/null | grep "Europe/" | sort | head -20
        echo ""
        
        echo "Asie :"
        systemsetup -listtimezones 2>/dev/null | grep "Asia/" | sort | head -20
        echo ""
        
        echo "Pacifique :"
        systemsetup -listtimezones 2>/dev/null | grep "Pacific/" | sort | head -20
        echo ""
        
        echo "Autres :"
        systemsetup -listtimezones 2>/dev/null | grep -v -E "America/|Europe/|Asia/|Pacific/" | sort | head -10
    else
        # Liste simple
        case "$filter_region" in
            "americas"|"america")
                systemsetup -listtimezones 2>/dev/null | grep "America/" | sort
                ;;
            "europe")
                systemsetup -listtimezones 2>/dev/null | grep "Europe/" | sort
                ;;
            "asia")
                systemsetup -listtimezones 2>/dev/null | grep "Asia/" | sort
                ;;
            "pacific")
                systemsetup -listtimezones 2>/dev/null | grep "Pacific/" | sort
                ;;
            *)
                systemsetup -listtimezones 2>/dev/null | sort
                ;;
        esac
    fi
}

# Valider le fuseau horaire
validate_timezone() {
    local timezone="$1"
    
    if [[ -z "$timezone" ]]; then
        echo "Erreur : Le fuseau horaire ne peut pas être vide"
        return 1
    fi
    
    # Vérifier si le fuseau horaire existe dans la liste système
    if systemsetup -listtimezones 2>/dev/null | grep -q "^$timezone$"; then
        echo "✅ Fuseau horaire '$timezone' est valide"
        return 0
    else
        echo "❌ Fuseau horaire '$timezone' n'est pas valide"
        echo "Utilisez la commande 'list-timezones' pour voir les options disponibles"
        return 1
    fi
}

# Définir le fuseau horaire avec validation entreprise
set_enterprise_timezone() {
    local timezone="$1"
    local policy="${2:-standard}"
    local force="${3:-false}"
    local admin_user=$(whoami)
    
    log_security_event "TIMEZONE_CHANGE_ATTEMPT" "timezone=$timezone,policy=$policy" "INFO"
    
    echo "=== Configuration Fuseau Horaire Entreprise ==="
    echo "Fuseau Horaire Cible : $timezone"
    echo "Politique : $policy"
    echo "Administrateur : $admin_user"
    echo "Mode Force : $force"
    echo ""
    
    # Valider le fuseau horaire
    if ! validate_timezone "$timezone"; then
        log_operation "ERROR" "Fuseau horaire invalide spécifié : $timezone"
        return 1
    fi
    
    # Vérifier le fuseau horaire actuel
    local current_tz=$(systemsetup -gettimezone 2>/dev/null | awk -F': ' '{print $2}')
    
    if [[ "$current_tz" == "$timezone" && "$force" != "true" ]]; then
        echo "✅ Fuseau horaire déjà défini sur $timezone"
        log_operation "INFO" "Fuseau horaire inchangé : $timezone"
        return 0
    fi
    
    # Sauvegarder la configuration actuelle
    local backup_file="$BACKUP_DIR/timezone_$(date +%Y%m%d_%H%M%S).conf"
    {
        echo "# Sauvegarde Fuseau Horaire Roundfleet"
        echo "PREVIOUS_TIMEZONE=$current_tz"
        echo "PREVIOUS_TIME_SERVER=$(systemsetup -getnetworktimeserver 2>/dev/null | awk -F': ' '{print $2}')"
        echo "PREVIOUS_NETWORK_TIME=$(systemsetup -getusingnetworktime 2>/dev/null | awk -F': ' '{print $2}')"
        echo "BACKUP_TIMESTAMP=$(date)"
        echo "CHANGED_BY=$admin_user"
    } > "$backup_file"
    
    log_operation "INFO" "Configuration sauvegardée dans : $backup_file"
    
    # Appliquer le changement de fuseau horaire
    echo "Définition du fuseau horaire sur : $timezone"
    
    if sudo systemsetup -settimezone "$timezone" 2>/dev/null; then
        echo "✅ Fuseau horaire défini avec succès"
        log_operation "INFO" "Fuseau horaire changé de '$current_tz' vers '$timezone'"
        log_security_event "TIMEZONE_CHANGED" "from=$current_tz,to=$timezone,policy=$policy" "INFO"
        
        # Configurer la synchronisation de l'heure réseau
        configure_time_sync "$policy"
        
        # Vérifier le changement
        sleep 2
        local new_tz=$(systemsetup -gettimezone 2>/dev/null | awk -F': ' '{print $2}')
        
        if [[ "$new_tz" == "$timezone" ]]; then
            echo "✅ Vérification du fuseau horaire réussie"
            
            # Afficher les informations de temps mises à jour
            get_current_timezone
            
            return 0
        else
            echo "❌ Vérification du fuseau horaire échouée"
            log_operation "ERROR" "Vérification fuseau horaire échouée : attendu '$timezone', obtenu '$new_tz'"
            return 1
        fi
    else
        echo "❌ Échec de définition du fuseau horaire"
        log_operation "ERROR" "Échec de définition du fuseau horaire sur : $timezone"
        log_security_event "TIMEZONE_CHANGE_FAILED" "timezone=$timezone,error=systemsetup_failed" "ERROR"
        return 1
    fi
}

# Configurer la synchronisation de l'heure
configure_time_sync() {
    local policy="${1:-standard}"
    local admin_user=$(whoami)
    
    echo "=== Configuration Synchronisation Heure ==="
    echo "Politique : $policy"
    echo ""
    
    # Déterminer le serveur de temps basé sur la politique
    local time_server
    case "$policy" in
        "enterprise")
            time_server="${ENTERPRISE_TIME_SERVERS[0]}"
            ;;
        "secure")
            time_server="${ENTERPRISE_TIME_SERVERS[1]}"
            ;;
        "standard")
            time_server="time.apple.com"
            ;;
        "public")
            time_server="pool.ntp.org"
            ;;
        *)
            time_server="time.apple.com"
            ;;
    esac
    
    echo "Définition du serveur de temps sur : $time_server"
    
    # Activer l'heure réseau et définir le serveur
    if sudo systemsetup -setusingnetworktime on -setnetworktimeserver "$time_server" 2>/dev/null; then
        echo "✅ Synchronisation de l'heure configurée avec succès"
        log_operation "INFO" "Sync temps configuré : serveur=$time_server, politique=$policy"
        
        # Tester la connectivité du serveur de temps
        test_time_server_connectivity "$time_server"
        
        return 0
    else
        echo "❌ Échec de configuration de la synchronisation de l'heure"
        log_operation "ERROR" "Échec config sync temps : serveur=$time_server"
        
        # Essayer les serveurs de fallback
        echo "Tentative de serveurs de temps de fallback..."
        for fallback_server in "${ENTERPRISE_TIME_SERVERS[@]}"; do
            if [[ "$fallback_server" != "$time_server" ]]; then
                echo "Tentative serveur fallback : $fallback_server"
                
                if sudo systemsetup -setusingnetworktime on -setnetworktimeserver "$fallback_server" 2>/dev/null; then
                    echo "✅ Serveur de temps fallback configuré : $fallback_server"
                    log_operation "INFO" "Sync temps fallback configuré : $fallback_server"
                    return 0
                fi
            fi
        done
        
        echo "❌ Toutes les configurations de serveur de temps ont échoué"
        log_operation "ERROR" "Toutes les configurations de serveur de temps ont échoué"
        return 1
    fi
}

# Tester la connectivité du serveur de temps
test_time_server_connectivity() {
    local time_server="$1"
    local timeout=10
    
    echo "Test de connectivité vers le serveur de temps : $time_server"
    
    # Tester la connectivité de base
    if timeout "$timeout" ping -c 3 "$time_server" &>/dev/null; then
        echo "✅ Serveur de temps accessible"
        
        # Tester la connectivité NTP spécifique (si ntpdate est disponible)
        if command -v ntpdate &>/dev/null; then
            if timeout "$timeout" ntpdate -q "$time_server" &>/dev/null; then
                echo "✅ Service NTP répond"
                return 0
            else
                echo "⚠️  Serveur de temps accessible mais NTP peut ne pas répondre"
                return 1
            fi
        else
            echo "✅ Connectivité de base confirmée (ntpdate non disponible pour test NTP)"
            return 0
        fi
    else
        echo "❌ Serveur de temps non accessible"
        log_operation "WARNING" "Connectivité serveur de temps échouée : $time_server"
        return 1
    fi
}

# Surveiller la dérive temporelle et la synchronisation
monitor_time_sync() {
    local check_type="${1:-basic}"
    local admin_user=$(whoami)
    
    echo "=== Surveillance Synchronisation Heure ==="
    echo "Type de Vérification : $check_type"
    echo "Surveillant : $admin_user"
    echo ""
    
    local sync_status="HEALTHY"
    local issues=()
    
    # Vérifier si l'heure réseau est activée
    local network_time_status=$(systemsetup -getusingnetworktime 2>/dev/null | awk -F': ' '{print $2}')
    
    if [[ "$network_time_status" == "On" ]]; then
        echo "✅ Synchronisation heure réseau activée"
    else
        echo "❌ Synchronisation heure réseau désactivée"
        sync_status="CRITICAL"
        issues+=("Sync heure réseau désactivée")
    fi
    
    # Vérifier la configuration du serveur de temps
    local time_server=$(systemsetup -getnetworktimeserver 2>/dev/null | awk -F': ' '{print $2}')
    echo "Serveur de Temps : $time_server"
    
    # Tester la connectivité du serveur de temps
    if ! test_time_server_connectivity "$time_server"; then
        sync_status="WARNING"
        issues+=("Problèmes de connectivité serveur de temps")
    fi
    
    # Vérifier la dérive temporelle (si ntpdate est disponible)
    if command -v ntpdate &>/dev/null; then
        echo ""
        echo "Vérification de la dérive temporelle..."
        
        local drift_output=$(ntpdate -q "$time_server" 2>/dev/null | tail -1)
        
        if [[ -n "$drift_output" ]]; then
            # Extraire la valeur de dérive (analyse simplifiée)
            local drift_seconds=$(echo "$drift_output" | grep -o "offset [+-][0-9.]*" | awk '{print $2}' | tr -d '+')
            
            if [[ -n "$drift_seconds" ]]; then
                local drift_abs=$(echo "$drift_seconds" | tr -d '-')
                
                echo "Dérive temporelle : ${drift_seconds}s"
                
                if (( $(echo "$drift_abs > $TIME_DRIFT_THRESHOLD" | bc -l) )); then
                    echo "⚠️  Dérive temporelle dépasse le seuil (${TIME_DRIFT_THRESHOLD}s)"
                    sync_status="WARNING"
                    issues+=("Dérive temporelle : ${drift_seconds}s")
                else
                    echo "✅ Dérive temporelle dans la plage acceptable"
                fi
            fi
        fi
    else
        echo "ntpdate non disponible pour vérification de dérive"
    fi
    
    # Vérifications avancées
    if [[ "$check_type" == "comprehensive" ]]; then
        echo ""
        echo "Exécution surveillance temps complète..."
        
        # Vérifier horloge système vs horloge matérielle
        if command -v hwclock &>/dev/null; then
            local sys_time=$(date +%s)
            local hw_time=$(sudo hwclock --show | date -f - +%s 2>/dev/null || echo "0")
            
            if [[ "$hw_time" != "0" ]]; then
                local clock_diff=$((sys_time - hw_time))
                local clock_diff_abs=${clock_diff#-}
                
                echo "Différence horloge système/matérielle : ${clock_diff}s"
                
                if [[ $clock_diff_abs -gt 30 ]]; then
                    sync_status="WARNING"
                    issues+=("Dérive horloge système/matérielle : ${clock_diff}s")
                fi
            fi
        fi
        
        # Vérifier les processus chronyd ou ntpd
        if pgrep -x "chronyd" &>/dev/null || pgrep -x "ntpd" &>/dev/null; then
            echo "✅ Démon de temps en cours d'exécution"
        else
            echo "⚠️  Aucun démon de temps détecté"
        fi
    fi
    
    # Générer le rapport de surveillance
    echo ""
    echo "=== Rapport État Sync Temps ==="
    echo "État Global : $sync_status"
    echo "Horodatage : $(date)"
    
    if [[ ${#issues[@]} -gt 0 ]]; then
        echo "Problèmes Trouvés :"
        printf '  - %s\n' "${issues[@]}"
    else
        echo "✅ Tous les systèmes de synchronisation temporelle opérationnels"
    fi
    
    # Enregistrer les résultats de surveillance
    log_operation "INFO" "Surveillance sync temps terminée : $sync_status (${#issues[@]} problèmes)"
    log_security_event "TIME_SYNC_CHECK" "status=$sync_status,issues=${#issues[@]}" "INFO"
    
    # Retourner le code de sortie approprié
    case "$sync_status" in
        "HEALTHY") return 0 ;;
        "WARNING") return 1 ;;
        "CRITICAL") return 2 ;;
        *) return 3 ;;
    esac
}

# Appliquer une politique géographique
apply_geographic_policy() {
    local policy_name="$1"
    local admin_user=$(whoami)
    
    log_security_event "GEOGRAPHIC_POLICY_APPLY" "policy=$policy_name" "INFO"
    
    echo "=== Application Politique Géographique ==="
    echo "Politique : $policy_name"
    echo "Administrateur : $admin_user"
    echo ""
    
    # Vérifier si la politique existe
    if [[ -z "${GEOGRAPHIC_POLICIES[$policy_name]}" ]]; then
        echo "❌ Politique géographique inconnue : $policy_name"
        echo ""
        echo "Politiques disponibles :"
        for policy in "${!GEOGRAPHIC_POLICIES[@]}"; do
            echo "  $policy -> ${GEOGRAPHIC_POLICIES[$policy]}"
        done
        return 1
    fi
    
    local target_timezone="${GEOGRAPHIC_POLICIES[$policy_name]}"
    
    echo "Fuseau horaire cible : $target_timezone"
    echo "Mapping politique : $policy_name -> $target_timezone"
    echo ""
    
    # Appliquer le changement de fuseau horaire
    set_enterprise_timezone "$target_timezone" "geographic_policy"
}

# Générer un rapport de conformité des fuseaux horaires
generate_timezone_report() {
    local report_type="${1:-summary}"
    local admin_user=$(whoami)
    local report_file="/var/reports/timezone_report_$(date +%Y%m%d_%H%M%S).txt"
    
    mkdir -p "$(dirname "$report_file")"
    
    log_security_event "REPORT_GENERATION" "type=$report_type" "INFO"
    
    {
        echo "Rapport Gestion Fuseau Horaire Roundfleet"
        echo "======================================"
        echo "Type de Rapport : $report_type"
        echo "Généré : $(date)"
        echo "Généré Par : $admin_user"
        echo "Nom d'hôte : $(hostname)"
        echo ""
        
        case "$report_type" in
            "summary")
                echo "== Résumé Fuseau Horaire =="
                get_current_timezone
                
                echo "Politiques Géographiques Disponibles :"
                for policy in "${!GEOGRAPHIC_POLICIES[@]}"; do
                    echo "  $policy: ${GEOGRAPHIC_POLICIES[$policy]}"
                done
                ;;
            "compliance")
                echo "== Évaluation Conformité =="
                
                # Vérifier les exigences de conformité
                local current_tz=$(systemsetup -gettimezone 2>/dev/null | awk -F': ' '{print $2}')
                local network_time=$(systemsetup -getusingnetworktime 2>/dev/null | awk -F': ' '{print $2}')
                local time_server=$(systemsetup -getnetworktimeserver 2>/dev/null | awk -F': ' '{print $2}')
                
                echo "Configuration Actuelle :"
                echo "  Fuseau Horaire : $current_tz"
                echo "  Sync Heure Réseau : $network_time"
                echo "  Serveur Temps : $time_server"
                echo ""
                
                echo "Standards de Conformité :"
                for standard in "${!COMPLIANCE_STANDARDS[@]}"; do
                    echo "  $standard: ${COMPLIANCE_STANDARDS[$standard]}"
                done
                ;;
            "audit")
                echo "== Information d'Audit =="
                if [[ -f "$AUDIT_LOG" ]]; then
                    echo "Événements fuseau horaire récents (20 derniers) :"
                    tail -20 "$AUDIT_LOG"
                else
                    echo "Aucun log d'audit disponible"
                fi
                ;;
        esac
        
        echo ""
        echo "== Informations Temps Système =="
        echo "Heure Locale : $(date)"
        echo "Heure UTC : $(date -u)"
        echo "Uptime : $(uptime)"
        
    } > "$report_file"
    
    echo "Rapport fuseau horaire généré : $report_file"
    log_operation "INFO" "Rapport fuseau horaire généré : $report_file"
}

# Définir une politique d'heures d'ouverture
set_business_hours_policy() {
    local policy_name="$1"
    local custom_hours="$2"
    
    echo "=== Configuration Politique Heures d'Ouverture ==="
    echo "Politique : $policy_name"
    
    if [[ "$policy_name" == "custom" && -n "$custom_hours" ]]; then
        echo "Heures Personnalisées : $custom_hours"
        BUSINESS_HOURS_POLICIES["custom"]="$custom_hours"
    fi
    
    local hours="${BUSINESS_HOURS_POLICIES[$policy_name]}"
    
    if [[ -z "$hours" ]]; then
        echo "❌ Politique heures d'ouverture inconnue : $policy_name"
        echo ""
        echo "Politiques disponibles :"
        for policy in "${!BUSINESS_HOURS_POLICIES[@]}"; do
            echo "  $policy: ${BUSINESS_HOURS_POLICIES[$policy]}"
        done
        return 1
    fi
    
    echo "Heures d'Ouverture : $hours"
    
    # Sauvegarder la politique dans le fichier de configuration
    local policy_file="$POLICIES_DIR/business_hours.conf"
    {
        echo "# Politique Heures d'Ouverture Roundfleet"
        echo "POLICY_NAME=$policy_name"
        echo "BUSINESS_HOURS=$hours"
        echo "CONFIGURED_BY=$(whoami)"
        echo "CONFIGURED_DATE=$(date)"
    } > "$policy_file"
    
    echo "✅ Politique heures d'ouverture configurée"
    log_operation "INFO" "Politique heures d'ouverture définie : $policy_name ($hours)"
}

# Fonction principale de gestion des fuseaux horaires
main() {
    local action="${1:-help}"
    
    case "$action" in
        "status"|"current")
            get_current_timezone
            ;;
        "list-timezones")
            local filter_region="$2"
            local format="${3:-grouped}"
            
            list_available_timezones "$filter_region" "$format"
            ;;
        "set")
            local timezone="$2"
            local policy="${3:-standard}"
            local force="$4"
            
            if [[ -z "$timezone" ]]; then
                echo "Usage : $0 set <timezone> [policy] [force]"
                echo "Exemple : $0 set America/New_York enterprise"
                return 1
            fi
            
            set_enterprise_timezone "$timezone" "$policy" "$force"
            ;;
        "validate")
            local timezone="$2"
            
            if [[ -z "$timezone" ]]; then
                echo "Usage : $0 validate <timezone>"
                return 1
            fi
            
            validate_timezone "$timezone"
            ;;
        "sync")
            local policy="${2:-standard}"
            
            configure_time_sync "$policy"
            ;;
        "monitor")
            local check_type="${2:-basic}"
            
            monitor_time_sync "$check_type"
            ;;
        "apply-policy")
            local policy_name="$2"
            
            if [[ -z "$policy_name" ]]; then
                echo "Usage : $0 apply-policy <policy_name>"
                echo ""
                echo "Politiques géographiques disponibles :"
                for policy in "${!GEOGRAPHIC_POLICIES[@]}"; do
                    echo "  $policy"
                done
                return 1
            fi
            
            apply_geographic_policy "$policy_name"
            ;;
        "business-hours")
            local policy_name="$2"
            local custom_hours="$3"
            
            if [[ -z "$policy_name" ]]; then
                echo "Usage : $0 business-hours <policy> [custom_hours]"
                echo ""
                echo "Politiques disponibles :"
                for policy in "${!BUSINESS_HOURS_POLICIES[@]}"; do
                    echo "  $policy"
                done
                return 1
            fi
            
            set_business_hours_policy "$policy_name" "$custom_hours"
            ;;
        "report")
            local report_type="${2:-summary}"
            
            generate_timezone_report "$report_type"
            ;;
        "help"|*)
            echo "$SCRIPT_NAME v$VERSION"
            echo "Gestion Entreprise des Fuseaux Horaires et Date/Heure"
            echo ""
            echo "Usage : $0 <action> [options]"
            echo ""
            echo "Actions :"
            echo "  status                                  - Afficher les informations fuseau horaire actuel"
            echo "  list-timezones [region] [format]        - Lister les fuseaux horaires disponibles"
            echo "  set <timezone> [policy] [force]         - Définir fuseau horaire avec politique"
            echo "  validate <timezone>                     - Valider le format du fuseau horaire"
            echo "  sync [policy]                           - Configurer la synchronisation de l'heure"
            echo "  monitor [type]                          - Surveiller la synchronisation de l'heure"
            echo "  apply-policy <policy>                   - Appliquer une politique géographique"
            echo "  business-hours <policy> [custom]        - Configurer les heures d'ouverture"
            echo "  report [type]                           - Générer des rapports de fuseau horaire"
            echo "  help                                    - Afficher ce message d'aide"
            echo ""
            echo "Politiques Géographiques :"
            for policy in "${!GEOGRAPHIC_POLICIES[@]}"; do
                echo "  $policy"
            done
            echo ""
            echo "Politiques Sync Temps :"
            echo "  enterprise  - Utiliser serveur NTP entreprise principal"
            echo "  secure      - Utiliser serveur NTP entreprise secondaire"
            echo "  standard    - Utiliser serveur temps Apple (défaut)"
            echo "  public      - Utiliser pool NTP public"
            echo ""
            echo "Politiques Heures d'Ouverture :"
            for policy in "${!BUSINESS_HOURS_POLICIES[@]}"; do
                echo "  $policy: ${BUSINESS_HOURS_POLICIES[$policy]}"
            done
            echo ""
            echo "Types de Surveillance :"
            echo "  basic       - Vérification statut sync temps de base"
            echo "  comprehensive - Surveillance étendue et diagnostics"
            echo ""
            echo "Types de Rapport :"
            echo "  summary     - Aperçu fuseau horaire (défaut)"
            echo "  compliance  - Évaluation conformité"
            echo "  audit       - Piste d'audit et événements"
            echo ""
            echo "Exemples :"
            echo "  $0 set America/New_York enterprise      - Définir heure Est avec politique entreprise"
            echo "  $0 apply-policy US_PACIFIC              - Appliquer politique Pacifique US"
            echo "  $0 monitor comprehensive                - Vérification surveillance complète"
            echo "  $0 business-hours extended              - Définir heures ouverture étendues"
            echo ""
            echo "Fonctionnalités :"
            echo "  • Gestion fuseaux horaires niveau entreprise"
            echo "  • Automation politique géographique"
            echo "  • Synchronisation temps avancée avec serveurs fallback"
            echo "  • Surveillance temps réel et détection dérive"
            echo "  • Journalisation audit complète et conformité"
            echo "  • Application politiques heures d'ouverture"
            echo "  • Intégration avec infrastructure Roundfleet"
            ;;
    esac
}

# Exécuter la fonction principale avec tous les arguments
main "$@"

Commandes de Référence Rapide

Opérations Fuseaux Horaires de Base

# Vérifier le statut du fuseau horaire actuel
./timezone_manager.sh status

# Lister les fuseaux horaires disponibles
./timezone_manager.sh list-timezones

# Définir fuseau horaire avec politique entreprise
./timezone_manager.sh set America/New_York enterprise

# Valider fuseau horaire avant définition
./timezone_manager.sh validate Europe/London

Gestion Politique Géographique

# Appliquer les politiques géographiques prédéfinies
./timezone_manager.sh apply-policy US_EAST
./timezone_manager.sh apply-policy EU_LONDON
./timezone_manager.sh apply-policy ASIA_TOKYO

# Lister toutes les politiques géographiques disponibles
./timezone_manager.sh apply-policy

Synchronisation Heure

# Configurer synchronisation heure avec différentes politiques
./timezone_manager.sh sync enterprise    # Utiliser serveurs NTP entreprise
./timezone_manager.sh sync standard      # Utiliser serveur temps Apple
./timezone_manager.sh sync public        # Utiliser pool NTP public

# Surveiller santé synchronisation heure
./timezone_manager.sh monitor basic
./timezone_manager.sh monitor comprehensive

Heures d'Ouverture et Conformité

# Définir politiques heures d'ouverture
./timezone_manager.sh business-hours standard     # 09:00-17:00
./timezone_manager.sh business-hours extended     # 08:00-18:00
./timezone_manager.sh business-hours 24x7         # Opérations 24/7
./timezone_manager.sh business-hours custom "06:00-22:00"

# Générer rapports de conformité
./timezone_manager.sh report compliance
./timezone_manager.sh report audit

Exemples d'Intégration

Intégration JAMF Pro

#!/bin/bash

# Script JAMF Pro pour gestion fuseau horaire
# Paramètres : $4 = politique_géographique, $5 = politique_sync, $6 = heures_ouverture

POLITIQUE_GEOGRAPHIQUE="$4"
POLITIQUE_SYNC="$5"
HEURES_OUVERTURE="$6"

# Télécharger gestionnaire fuseau horaire s'il n'est pas présent
if [[ ! -f "/usr/local/bin/roundfleet_timezone_manager.sh" ]]; then
    curl -o "/usr/local/bin/roundfleet_timezone_manager.sh" \
         "https://scripts.roundfleet.com/timezone_manager.sh"
    chmod +x "/usr/local/bin/roundfleet_timezone_manager.sh"
fi

# Appliquer politique géographique
if [[ -n "$POLITIQUE_GEOGRAPHIQUE" ]]; then
    /usr/local/bin/roundfleet_timezone_manager.sh apply-policy "$POLITIQUE_GEOGRAPHIQUE"
fi

# Configurer synchronisation heure
if [[ -n "$POLITIQUE_SYNC" ]]; then
    /usr/local/bin/roundfleet_timezone_manager.sh sync "$POLITIQUE_SYNC"
fi

# Définir heures d'ouverture
if [[ -n "$HEURES_OUVERTURE" ]]; then
    /usr/local/bin/roundfleet_timezone_manager.sh business-hours "$HEURES_OUVERTURE"
fi

# Rapporter statut à JAMF
echo "Configuration fuseau horaire terminée avec succès"

Meilleures Pratiques

  1. Utiliser serveurs NTP entreprise pour synchronisation temporelle cohérente
  2. Implémenter politiques géographiques pour organisations multi-sites
  3. Surveiller dérive temporelle en continu avec alertes automatisées
  4. Maintenir pistes d'audit pour exigences de conformité
  5. Tester connectivité serveur temps avant déploiement
  6. Utiliser serveurs temps de sauvegarde pour redondance
  7. Coordonner avec équipes réseau pour accès serveurs NTP
  8. Documenter politiques fuseaux horaires pour opérations métier

Ce système de gestion des fuseaux horaires entreprise fournit un contrôle complet du temps et de la date avec conformité géographique automatisée, application de politiques et capacités de surveillance de niveau entreprise pour une gestion temporelle Roundfleet efficace.

Gestion d'Entreprise des Sauvegardes Time Machine sur macOS

Gérez et automatisez les sauvegardes Time Machine de votre Roundfleet avec des politiques de sauvegarde de niveau entreprise et des capacités de récupération d'urgence. Ce tutoriel couvre la gestion avancée des sauvegardes, le déploiement à l'échelle de la flotte, la surveillance de conformité et les systèmes de récupération automatisés.

Comprendre la Gestion Time Machine d'Entreprise

La gestion des sauvegardes d'entreprise nécessite :

  • 🔄 Politiques de sauvegarde automatisées - Planifications de sauvegarde cohérentes sur tous les appareils
  • 🛡️ Planification de récupération d'urgence - Récupération rapide des incidents de perte de données
  • 📊 Surveillance de conformité - Pistes d'audit et conformité réglementaire
  • ⚡ Gestion de flotte - Contrôle et rapports de sauvegarde centralisés
  • 🔐 Sécurité et chiffrement - Données de sauvegarde protégées avec contrôles d'accès

Opérations de Base Time Machine

Définir la Destination de Sauvegarde

#!/bin/bash

# Définir la destination de sauvegarde Time Machine
BACKUP_DESTINATION="/Volumes/BackupDrive"

if [[ -d "$BACKUP_DESTINATION" ]]; then
    sudo tmutil setdestination "$BACKUP_DESTINATION"
    echo "✅ Destination de sauvegarde définie vers : $BACKUP_DESTINATION"
else
    echo "❌ Destination de sauvegarde non trouvée : $BACKUP_DESTINATION"
    exit 1
fi

Activer et Démarrer la Sauvegarde

#!/bin/bash

# Activer Time Machine et démarrer la sauvegarde
sudo tmutil enable
sudo tmutil startbackup

echo "✅ Time Machine activé et sauvegarde démarrée"

Vérifier le Statut de Sauvegarde

#!/bin/bash

# Vérifier le statut actuel de la sauvegarde
tmutil status

echo "📊 Statut actuel de sauvegarde affiché"

Lister les Sauvegardes Disponibles

#!/bin/bash

# Lister toutes les sauvegardes disponibles
tmutil listbackups

echo "📋 Sauvegardes disponibles listées"

Gestion Avancée des Sauvegardes

Configuration Intelligente de Destination de Sauvegarde

#!/bin/bash

# Destination de sauvegarde intelligente avec validation
setup_backup_destination() {
    local destination="$1"
    local min_space_gb="${2:-100}"  # Minimum 100GB par défaut
    
    echo "🔍 Validation de la destination de sauvegarde : $destination"
    
    # Vérifier si la destination existe
    if [[ ! -d "$destination" ]]; then
        echo "❌ Le répertoire de destination n'existe pas : $destination"
        return 1
    fi
    
    # Vérifier l'espace disponible
    local available_space=$(df -BG "$destination" | tail -1 | awk '{print $4}' | sed 's/G//')
    
    if [[ $available_space -lt $min_space_gb ]]; then
        echo "❌ Espace insuffisant : ${available_space}GB disponible, ${min_space_gb}GB requis"
        return 1
    fi
    
    # Vérifier les permissions d'écriture
    if [[ ! -w "$destination" ]]; then
        echo "❌ Pas de permission d'écriture vers la destination : $destination"
        return 1
    fi
    
    # Définir la destination
    sudo tmutil setdestination "$destination"
    
    if [[ $? -eq 0 ]]; then
        echo "✅ Destination de sauvegarde définie avec succès : $destination"
        echo "📊 Espace disponible : ${available_space}GB"
        return 0
    else
        echo "❌ Échec de la définition de la destination de sauvegarde"
        return 1
    fi
}

# Exemple d'utilisation
setup_backup_destination "/Volumes/Enterprise_Backup" 500

Gestion Avancée des Exclusions

#!/bin/bash

# Gestion des exclusions de sauvegarde d'entreprise
manage_backup_exclusions() {
    local action="$1"  # add, remove, list
    local path="$2"
    
    case "$action" in
        "add")
            if [[ -n "$path" ]]; then
                sudo tmutil addexclusion "$path"
                echo "✅ Exclusion ajoutée : $path"
                log_exclusion_change "added" "$path"
            else
                echo "❌ Chemin requis pour l'opération d'ajout"
                return 1
            fi
            ;;
        "remove")
            if [[ -n "$path" ]]; then
                sudo tmutil removeexclusion "$path"
                echo "✅ Exclusion supprimée : $path"
                log_exclusion_change "removed" "$path"
            else
                echo "❌ Chemin requis pour l'opération de suppression"
                return 1
            fi
            ;;
        "list")
            echo "📋 Exclusions actuelles :"
            tmutil listbackups | while read -r backup; do
                if [[ -d "$backup" ]]; then
                    echo "Vérification des exclusions pour : $backup"
                    # Lister les exclusions nécessiterait l'analyse des métadonnées de sauvegarde
                fi
            done
            ;;
        "enterprise_defaults")
            apply_enterprise_exclusions
            ;;
        *)
            echo "❌ Action invalide : $action"
            echo "Actions disponibles : add, remove, list, enterprise_defaults"
            return 1
            ;;
    esac
}

# Appliquer les exclusions d'entreprise standard
apply_enterprise_exclusions() {
    echo "🏢 Application des exclusions de sauvegarde d'entreprise..."
    
    local exclusions=(
        "/System/Library/Caches"
        "/Library/Caches"
        "~/Library/Caches"
        "/private/var/vm"
        "/cores"
        "/tmp"
        "/private/tmp"
        "~/.Trash"
        "/Applications/Xcode.app/Contents/Developer/Platforms"  # Gros fichiers de dev
        "/usr/local/var/log"  # Fichiers de log
        "~/Downloads"  # Téléchargements temporaires
    )
    
    for exclusion in "${exclusions[@]}"; do
        sudo tmutil addexclusion "$exclusion" 2>/dev/null
        echo "Exclusion ajoutée : $exclusion"
    done
    
    echo "✅ Exclusions d'entreprise appliquées"
}

# Journaliser les changements d'exclusion pour audit
log_exclusion_change() {
    local action="$1"
    local path="$2"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    local log_entry="[$timestamp] Exclusion $action : $path"
    
    echo "$log_entry" >> "/var/log/roundfleet_backup_exclusions.log"
}

Surveillance de la Santé des Sauvegardes

#!/bin/bash

# Évaluation complète de la santé des sauvegardes
assess_backup_health() {
    echo "🏥 Évaluation de la santé des sauvegardes Time Machine..."
    
    local health_score=100
    local issues=()
    local warnings=()
    
    # Vérifier si Time Machine est activé
    local tm_enabled=$(tmutil status | grep "Running" | wc -l)
    if [[ $tm_enabled -eq 0 ]]; then
        health_score=$((health_score - 30))
        issues+=("Time Machine n'est pas en cours d'exécution")
    fi
    
    # Vérifier l'accessibilité des destinations de sauvegarde
    local destinations=$(tmutil destinationinfo | grep "URL" | wc -l)
    if [[ $destinations -eq 0 ]]; then
        health_score=$((health_score - 25))
        issues+=("Aucune destination de sauvegarde configurée")
    else
        # Vérifier si les destinations sont accessibles
        tmutil destinationinfo | grep "URL" | while read -r line; do
            local dest_path=$(echo "$line" | sed 's/.*URL : //')
            if [[ ! -d "$dest_path" ]]; then
                health_score=$((health_score - 15))
                issues+=("Destination de sauvegarde inaccessible : $dest_path")
            fi
        done
    fi
    
    # Vérifier l'heure de la dernière sauvegarde
    local last_backup=$(tmutil latestbackup 2>/dev/null)
    if [[ -n "$last_backup" ]]; then
        local last_backup_timestamp=$(stat -f %m "$last_backup" 2>/dev/null)
        local current_timestamp=$(date +%s)
        local hours_since_backup=$(( (current_timestamp - last_backup_timestamp) / 3600 ))
        
        if [[ $hours_since_backup -gt 48 ]]; then
            health_score=$((health_score - 20))
            issues+=("Dernière sauvegarde il y a $hours_since_backup heures")
        elif [[ $hours_since_backup -gt 24 ]]; then
            health_score=$((health_score - 10))
            warnings+=("Dernière sauvegarde il y a $hours_since_backup heures")
        fi
    else
        health_score=$((health_score - 25))
        issues+=("Aucune sauvegarde précédente trouvée")
    fi
    
    # Vérifier l'espace disque disponible sur la destination de sauvegarde
    local backup_dest=$(tmutil destinationinfo | grep "URL" | head -1 | sed 's/.*URL : //')
    if [[ -n "$backup_dest" ]] && [[ -d "$backup_dest" ]]; then
        local available_space=$(df -BG "$backup_dest" | tail -1 | awk '{print $4}' | sed 's/G//')
        if [[ $available_space -lt 10 ]]; then
            health_score=$((health_score - 15))
            issues+=("Espace disque faible sur la destination de sauvegarde : ${available_space}GB")
        elif [[ $available_space -lt 50 ]]; then
            warnings+=("L'espace de destination de sauvegarde devient faible : ${available_space}GB")
        fi
    fi
    
    # Générer le rapport de santé
    echo "📊 Score de Santé de Sauvegarde : $health_score/100"
    
    if [[ ${#issues[@]} -gt 0 ]]; then
        echo "🔴 Problèmes Critiques :"
        printf '   - %s\n' "${issues[@]}"
    fi
    
    if [[ ${#warnings[@]} -gt 0 ]]; then
        echo "⚠️ Avertissements :"
        printf '   - %s\n' "${warnings[@]}"
    fi
    
    if [[ $health_score -ge 90 ]]; then
        echo "✅ Le système de sauvegarde est en bonne santé"
    elif [[ $health_score -ge 70 ]]; then
        echo "⚠️ Le système de sauvegarde a des problèmes mineurs"
    else
        echo "🔴 Le système de sauvegarde nécessite une attention immédiate"
    fi
    
    return $health_score
}

Politiques de Sauvegarde d'Entreprise

Politique d'Environnement de Production

#!/bin/bash

# Politique de sauvegarde de production haute fréquence
apply_production_backup_policy() {
    echo "🏭 Application de la politique de sauvegarde de production..."
    
    # Activer Time Machine
    sudo tmutil enable
    
    # Définir un planning de sauvegarde agressif (toutes les 30 minutes)
    configure_backup_intervals 1800 900 600 60
    
    # Appliquer des exclusions minimales (conserver la plupart des données)
    local minimal_exclusions=(
        "/System/Library/Caches"
        "/private/var/vm"
        "/cores"
    )
    
    for exclusion in "${minimal_exclusions[@]}"; do
        sudo tmutil addexclusion "$exclusion" 2>/dev/null
    done
    
    # Activer la vérification de sauvegarde
    enable_backup_verification
    
    echo "✅ Politique de sauvegarde de production appliquée"
    log_policy_application "production"
}

Politique d'Environnement de Développement

#!/bin/bash

# Politique de sauvegarde optimisée pour le développement
apply_development_backup_policy() {
    echo "💻 Application de la politique de sauvegarde de développement..."
    
    # Activer Time Machine
    sudo tmutil enable
    
    # Définir un planning de sauvegarde modéré (toutes les 2 heures)
    configure_backup_intervals 7200 3600 1800 300
    
    # Exclure les artefacts de développement
    local dev_exclusions=(
        "/System/Library/Caches"
        "/Library/Caches"
        "~/Library/Caches"
        "/private/var/vm"
        "/cores"
        "~/Library/Developer/Xcode/DerivedData"
        "~/Library/Developer/CoreSimulator"
        "*/node_modules"
        "*/.git/objects"
        "*/target"
        "*/build"
        "*/.gradle"
        "*/.npm"
    )
    
    for exclusion in "${dev_exclusions[@]}"; do
        sudo tmutil addexclusion "$exclusion" 2>/dev/null
    done
    
    echo "✅ Politique de sauvegarde de développement appliquée"
    log_policy_application "development"
}

Politique Exécutive/Minimale

#!/bin/bash

# Politique de sauvegarde légère pour les cadres
apply_executive_backup_policy() {
    echo "🏢 Application de la politique de sauvegarde exécutive..."
    
    # Activer Time Machine
    sudo tmutil enable
    
    # Définir un planning de sauvegarde standard (toutes les 4 heures)
    configure_backup_intervals 14400 7200 3600 600
    
    # Exclure les fichiers non essentiels
    local executive_exclusions=(
        "/System/Library/Caches"
        "/Library/Caches"
        "~/Library/Caches"
        "/private/var/vm"
        "/cores"
        "~/Downloads"
        "~/Movies"
        "/Applications/Games"
        "~/Library/Application Support/Steam"
    )
    
    for exclusion in "${executive_exclusions[@]}"; do
        sudo tmutil addexclusion "$exclusion" 2>/dev/null
    done
    
    echo "✅ Politique de sauvegarde exécutive appliquée"
    log_policy_application "executive"
}