Guide

Nouvelles mises à jour et améliorations de Macfleet.

Gestion des Mots de Passe d'Entreprise sur macOS

Implémentez une gestion complète des mots de passe et un contrôle d'authentification sur vos appareils MacFleet en utilisant des outils avancés de services d'annuaire et d'administration système. Ce tutoriel couvre l'effacement de mots de passe, l'application de politiques et la gestion d'authentification d'entreprise.

Comprendre la Gestion des Mots de Passe macOS

macOS fournit plusieurs outils pour la gestion des mots de passe :

  • dscl - Utilitaire en ligne de commande des Services d'Annuaire pour la gestion utilisateur
  • sysadminctl - Outil de contrôle d'administrateur système pour les opérations utilisateur
  • Services d'Annuaire - Framework central d'authentification et d'autorisation
  • Framework de Sécurité - Mécanismes avancés de politique et d'application de mots de passe

Opérations de Base sur les Mots de Passe

Effacer le Mot de Passe Utilisateur (Méthode de Base)

#!/bin/bash

# Effacement de base du mot de passe avec dscl
clear_user_password_dscl() {
    local username="$1"
    local current_password="$2"
    
    echo "=== Effacement du Mot de Passe pour l'Utilisateur : $username ==="
    
    # Valider les paramètres
    if [[ -z "$username" || -z "$current_password" ]]; then
        echo "❌ Usage : clear_user_password_dscl <nom_utilisateur> <mot_de_passe_actuel>"
        return 1
    fi
    
    # Vérifier si l'utilisateur existe
    if ! dscl . -read "/Users/$username" >/dev/null 2>&1; then
        echo "❌ L'utilisateur '$username' n'existe pas"
        return 1
    fi
    
    # Effacer le mot de passe avec dscl
    echo "Effacement du mot de passe pour l'utilisateur : $username"
    if dscl . passwd "/Users/$username" "$current_password" ""; then
        echo "✅ Mot de passe effacé avec succès pour l'utilisateur : $username"
        echo "ℹ️  L'utilisateur peut maintenant se connecter en appuyant sur Entrée sans mot de passe"
    else
        echo "❌ Échec d'effacement du mot de passe pour l'utilisateur : $username"
        echo "   Vérifiez que le mot de passe actuel est correct"
        return 1
    fi
}

# Usage : clear_user_password_dscl "jean.dupont" "motdepasseactuel123"

Effacer le Mot de Passe avec sysadminctl

#!/bin/bash

# Effacement avancé du mot de passe avec sysadminctl
clear_user_password_sysadminctl() {
    local target_username="$1"
    local admin_username="$2"
    local admin_password="$3"
    
    echo "=== Effacement du Mot de Passe avec sysadminctl ==="
    echo "Utilisateur cible : $target_username"
    echo "Utilisateur admin : $admin_username"
    
    # Valider les paramètres
    if [[ -z "$target_username" || -z "$admin_username" || -z "$admin_password" ]]; then
        echo "❌ Usage : clear_user_password_sysadminctl <utilisateur_cible> <utilisateur_admin> <mot_de_passe_admin>"
        return 1
    fi
    
    # Vérifier si l'utilisateur cible existe
    if ! dscl . -read "/Users/$target_username" >/dev/null 2>&1; then
        echo "❌ L'utilisateur cible '$target_username' n'existe pas"
        return 1
    fi
    
    # Vérifier si l'utilisateur admin existe et a les privilèges admin
    if ! dscl . -read "/Users/$admin_username" >/dev/null 2>&1; then
        echo "❌ L'utilisateur admin '$admin_username' n'existe pas"
        return 1
    fi
    
    # Effacer le mot de passe avec sysadminctl
    echo "Effacement du mot de passe pour l'utilisateur : $target_username"
    if sysadminctl -resetPasswordFor "$target_username" -newPassword "" -adminUser "$admin_username" -adminPassword "$admin_password"; then
        echo "✅ Mot de passe effacé avec succès pour l'utilisateur : $target_username"
        echo "ℹ️  L'utilisateur peut maintenant se connecter sans saisir de mot de passe"
    else
        echo "❌ Échec d'effacement du mot de passe pour l'utilisateur : $target_username"
        echo "   Vérifiez les identifiants admin et les permissions utilisateur"
        return 1
    fi
}

# Usage : clear_user_password_sysadminctl "marie.martin" "admin" "motdepasseadmin123"

Gestion Avancée des Mots de Passe

Vérifier le Statut du Mot de Passe

#!/bin/bash

# Vérifier le statut du mot de passe et de l'authentification utilisateur
check_password_status() {
    local username="$1"
    
    echo "=== Vérification du Statut de Mot de Passe pour l'Utilisateur : $username ==="
    
    if [[ -z "$username" ]]; then
        echo "❌ Usage : check_password_status <nom_utilisateur>"
        return 1
    fi
    
    # Vérifier si l'utilisateur existe
    if ! dscl . -read "/Users/$username" >/dev/null 2>&1; then
        echo "❌ L'utilisateur '$username' n'existe pas"
        return 1
    fi
    
    # Obtenir les informations utilisateur
    echo "Informations Utilisateur :"
    echo "Nom Réel : $(dscl . -read "/Users/$username" RealName | cut -d' ' -f2- || echo 'Non défini')"
    echo "UID : $(dscl . -read "/Users/$username" UniqueID | awk '{print $2}')"
    echo "ID Groupe Principal : $(dscl . -read "/Users/$username" PrimaryGroupID | awk '{print $2}')"
    echo "Répertoire Personnel : $(dscl . -read "/Users/$username" NFSHomeDirectory | cut -d' ' -f2-)"
    echo "Shell : $(dscl . -read "/Users/$username" UserShell | cut -d' ' -f2-)"
    
    # Vérifier la politique de mot de passe
    echo ""
    echo "Informations de Politique de Mot de Passe :"
    local password_policy=$(pwpolicy -u "$username" -getpolicy 2>/dev/null || echo "Aucune politique spécifique")
    echo "Politique de Mot de Passe : $password_policy"
    
    # Vérifier le statut du compte
    echo ""
    echo "Statut du Compte :"
    local account_policy=$(pwpolicy -u "$username" -getaccountpolicy 2>/dev/null || echo "Aucune politique de compte")
    echo "Politique de Compte : $account_policy"
    
    # Vérifier si le mot de passe est vide
    echo ""
    echo "Statut du Mot de Passe :"
    local auth_authority=$(dscl . -read "/Users/$username" AuthenticationAuthority 2>/dev/null)
    if [[ -z "$auth_authority" ]] || echo "$auth_authority" | grep -q "ShadowHash"; then
        echo "Type de Mot de Passe : Shadow Hash (Standard)"
    else
        echo "Type de Mot de Passe : $auth_authority"
    fi
}

check_password_status

Définir un Mot de Passe Sécurisé

#!/bin/bash

# Définir un mot de passe sécurisé avec validation
set_secure_password() {
    local username="$1"
    local new_password="$2"
    local admin_username="$3"
    local admin_password="$4"
    
    echo "=== Définition d'un Mot de Passe Sécurisé pour l'Utilisateur : $username ==="
    
    # Valider les paramètres
    if [[ -z "$username" || -z "$new_password" || -z "$admin_username" || -z "$admin_password" ]]; then
        echo "❌ Usage : set_secure_password <nom_utilisateur> <nouveau_mot_de_passe> <utilisateur_admin> <mot_de_passe_admin>"
        return 1
    fi
    
    # Vérifier la force du mot de passe
    if ! validate_password_strength "$new_password"; then
        echo "❌ Le mot de passe ne répond pas aux exigences de sécurité"
        return 1
    fi
    
    # Définir le mot de passe avec sysadminctl
    echo "Définition d'un mot de passe sécurisé pour l'utilisateur : $username"
    if sysadminctl -resetPasswordFor "$username" -newPassword "$new_password" -adminUser "$admin_username" -adminPassword "$admin_password"; then
        echo "✅ Mot de passe sécurisé défini avec succès pour l'utilisateur : $username"
        
        # Appliquer la politique de mot de passe
        apply_password_policy "$username"
    else
        echo "❌ Échec de définition du mot de passe pour l'utilisateur : $username"
        return 1
    fi
}

# Valider la force du mot de passe
validate_password_strength() {
    local password="$1"
    local min_length=8
    local has_upper=false
    local has_lower=false
    local has_digit=false
    local has_special=false
    
    # 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 lettre majuscule
    if [[ "$password" =~ [A-Z] ]]; then
        has_upper=true
    fi
    
    # Vérifier la présence d'une lettre minuscule
    if [[ "$password" =~ [a-z] ]]; then
        has_lower=true
    fi
    
    # Vérifier la présence d'un chiffre
    if [[ "$password" =~ [0-9] ]]; then
        has_digit=true
    fi
    
    # Vérifier la présence d'un caractère spécial
    if [[ "$password" =~ [^a-zA-Z0-9] ]]; then
        has_special=true
    fi
    
    # Valider toutes les exigences
    if [[ "$has_upper" == true && "$has_lower" == true && "$has_digit" == true && "$has_special" == true ]]; then
        echo "✅ Le mot de passe répond aux exigences de sécurité"
        return 0
    else
        echo "⚠️  Le mot de passe doit contenir majuscule, minuscule, chiffre et caractère spécial"
        return 1
    fi
}

# Appliquer la politique de mot de passe
apply_password_policy() {
    local username="$1"
    
    echo "Application de la politique de mot de passe pour l'utilisateur : $username"
    
    # Définir la politique de mot de passe (nécessite des privilèges admin)
    pwpolicy -u "$username" -setpolicy "minChars=8 requiresAlpha requiresNumeric requiresMixedCase requiresSymbol passwordCannotBeName maxMinutesUntilChangePassword=7776000" 2>/dev/null || true
    
    echo "✅ Politique de mot de passe appliquée"
}

Système de Gestion des Mots de Passe d'Entreprise

#!/bin/bash

# Système de Gestion des Mots de Passe d'Entreprise MacFleet
# Gestion complète de l'authentification utilisateur et des politiques de mots de passe

# Configuration
PASSWORD_CONFIG_FILE="/etc/macfleet/password_config.conf"
LOG_FILE="/var/log/macfleet_password_management.log"
AUDIT_FILE="/var/log/macfleet_password_audit.log"
BACKUP_DIR="/var/backups/macfleet/user_accounts"

# Paramètres par défaut
DEFAULT_MIN_PASSWORD_LENGTH=12
DEFAULT_PASSWORD_EXPIRY_DAYS=90
DEFAULT_MAX_FAILED_ATTEMPTS=5
DEFAULT_LOCKOUT_DURATION=30

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

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

# Charger la configuration de gestion des mots de passe
load_password_config() {
    if [[ -f "$PASSWORD_CONFIG_FILE" ]]; then
        source "$PASSWORD_CONFIG_FILE"
        log_action "Configuration de mot de passe chargée depuis $PASSWORD_CONFIG_FILE"
    else
        log_action "Utilisation de la configuration de mot de passe par défaut"
    fi
}

# Sauvegarder les informations de compte utilisateur
backup_user_account() {
    local username="$1"
    local backup_file="$BACKUP_DIR/user_backup_${username}_$(date +%Y%m%d_%H%M%S).plist"
    
    # Créer le répertoire de sauvegarde
    sudo mkdir -p "$BACKUP_DIR"
    
    # Exporter l'enregistrement utilisateur
    if dscl . -read "/Users/$username" > "$backup_file" 2>/dev/null; then
        log_action "Sauvegarde de compte utilisateur créée : $backup_file"
        audit_log "SAUVEGARDE_CRÉÉE pour l'utilisateur : $username"
    else
        log_action "Échec de création de sauvegarde pour l'utilisateur : $username"
    fi
}

# Effacement de mot de passe d'entreprise avec vérifications de sécurité
enterprise_clear_password() {
    local username="$1"
    local admin_username="$2"
    local admin_password="$3"
    local force_clear="${4:-false}"
    
    log_action "Démarrage de l'effacement de mot de passe d'entreprise pour l'utilisateur : $username"
    audit_log "EFFACEMENT_MOT_DE_PASSE_INITIÉ pour l'utilisateur : $username par l'admin : $admin_username"
    
    # Valider les paramètres
    if [[ -z "$username" || -z "$admin_username" || -z "$admin_password" ]]; then
        log_action "❌ Paramètres requis manquants pour l'effacement de mot de passe"
        return 1
    fi
    
    # Vérifier si l'utilisateur existe
    if ! dscl . -read "/Users/$username" >/dev/null 2>&1; then
        log_action "❌ L'utilisateur '$username' n'existe pas"
        return 1
    fi
    
    # Vérifications de sécurité
    if ! perform_security_checks "$username" "$force_clear"; then
        log_action "❌ Échec des vérifications de sécurité pour l'utilisateur : $username"
        return 1
    fi
    
    # Créer une sauvegarde avant de faire des changements
    backup_user_account "$username"
    
    # Effacer le mot de passe avec sysadminctl (méthode plus sécurisée)
    log_action "Effacement du mot de passe pour l'utilisateur : $username avec sysadminctl"
    if sysadminctl -resetPasswordFor "$username" -newPassword "" -adminUser "$admin_username" -adminPassword "$admin_password" 2>/dev/null; then
        log_action "✅ Mot de passe effacé avec succès pour l'utilisateur : $username"
        audit_log "MOT_DE_PASSE_EFFACÉ pour l'utilisateur : $username"
        
        # Appliquer les mesures de sécurité post-effacement
        apply_post_clear_security "$username"
        
        # Générer un rapport de conformité
        generate_password_compliance_report "$username"
        
        return 0
    else
        log_action "❌ Échec d'effacement du mot de passe pour l'utilisateur : $username"
        audit_log "ÉCHEC_EFFACEMENT_MOT_DE_PASSE pour l'utilisateur : $username"
        return 1
    fi
}

# Effectuer des vérifications de sécurité avant les opérations de mot de passe
perform_security_checks() {
    local username="$1"
    local force_clear="$2"
    
    log_action "Exécution des vérifications de sécurité pour l'utilisateur : $username"
    
    # Vérifier si l'utilisateur est admin (précaution supplémentaire requise)
    if dscl . -read "/Groups/admin" GroupMembership 2>/dev/null | grep -q "$username"; then
        if [[ "$force_clear" != "true" ]]; then
            log_action "⚠️  L'utilisateur '$username' est un administrateur - utilisez force_clear=true pour procéder"
            return 1
        else
            log_action "⚠️  Procédure avec effacement de mot de passe utilisateur admin (forcé)"
            audit_log "EFFACEMENT_MOT_DE_PASSE_ADMIN_FORCÉ pour l'utilisateur : $username"
        fi
    fi
    
    # Vérifier le statut FileVault
    if fdesetup status | grep -q "FileVault is On"; then
        local filevault_users=$(fdesetup list | cut -d',' -f1)
        if echo "$filevault_users" | grep -q "$username"; then
            log_action "⚠️  L'utilisateur '$username' est un utilisateur FileVault - l'effacement de mot de passe peut affecter le chiffrement du disque"
            audit_log "EFFACEMENT_MOT_DE_PASSE_UTILISATEUR_FILEVAULT pour l'utilisateur : $username"
        fi
    fi
    
    # Vérifier si l'utilisateur est actuellement connecté
    if who | grep -q "$username"; then
        log_action "⚠️  L'utilisateur '$username' est actuellement connecté"
        audit_log "EFFACEMENT_MOT_DE_PASSE_UTILISATEUR_ACTIF pour l'utilisateur : $username"
    fi
    
    # Vérifier l'heure de dernière connexion
    local last_login=$(last "$username" | head -1 | awk '{print $4, $5, $6}')
    log_action "Dernière connexion pour l'utilisateur '$username' : $last_login"
    
    return 0
}

# Appliquer des mesures de sécurité après l'effacement du mot de passe
apply_post_clear_security() {
    local username="$1"
    
    log_action "Application des mesures de sécurité post-effacement pour l'utilisateur : $username"
    
    # Définir la politique de compte pour exiger un changement de mot de passe à la prochaine connexion
    pwpolicy -u "$username" -setpolicy "requiresPasswordReset=1" 2>/dev/null || true
    
    # Enregistrer l'événement de sécurité
    audit_log "SÉCURITÉ_POST_EFFACEMENT_APPLIQUÉE pour l'utilisateur : $username"
    
    # Optionnel : Envoyer une notification à l'équipe de sécurité
    if [[ "${ENABLE_SECURITY_NOTIFICATIONS}" == "true" ]]; then
        send_security_notification "$username" "password_cleared"
    fi
}

# Générer un rapport de conformité des mots de passe
generate_password_compliance_report() {
    local username="$1"
    local report_file="/var/log/macfleet_password_compliance_$(date +%Y%m%d_%H%M%S).json"
    
    # Obtenir les informations utilisateur
    local uid=$(dscl . -read "/Users/$username" UniqueID 2>/dev/null | awk '{print $2}')
    local real_name=$(dscl . -read "/Users/$username" RealName 2>/dev/null | cut -d' ' -f2-)
    local home_dir=$(dscl . -read "/Users/$username" NFSHomeDirectory 2>/dev/null | cut -d' ' -f2-)
    
    # Vérifier le statut admin
    local is_admin=false
    if dscl . -read "/Groups/admin" GroupMembership 2>/dev/null | grep -q "$username"; then
        is_admin=true
    fi
    
    # Vérifier le statut FileVault
    local is_filevault_user=false
    if fdesetup status | grep -q "FileVault is On"; then
        if fdesetup list | cut -d',' -f1 | grep -q "$username"; then
            is_filevault_user=true
        fi
    fi
    
    # Générer le rapport de conformité
    local compliance_data='{
        "timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'",
        "device_id": "'$(system_profiler SPHardwareDataType | grep "Hardware UUID" | awk '{print $3}')'",
        "hostname": "'$(hostname)'",
        "operation": "password_cleared",
        "user_details": {
            "username": "'$username'",
            "uid": "'$uid'",
            "real_name": "'$real_name'",
            "home_directory": "'$home_dir'",
            "is_admin": '$is_admin',
            "is_filevault_user": '$is_filevault_user'
        },
        "security_status": {
            "password_cleared": true,
            "backup_created": true,
            "security_checks_passed": true,
            "post_clear_measures_applied": true
        }
    }'
    
    # Sauvegarder le rapport de conformité
    echo "$compliance_data" | jq . > "$report_file"
    log_action "Rapport de conformité des mots de passe généré : $report_file"
}

# Opérations de mots de passe en lot pour plusieurs utilisateurs
bulk_password_operations() {
    local operation="$1"
    local users_file="$2"
    local admin_username="$3"
    local admin_password="$4"
    
    log_action "Démarrage des opérations de mots de passe en lot : $operation"
    
    if [[ ! -f "$users_file" ]]; then
        log_action "❌ Fichier utilisateurs non trouvé : $users_file"
        return 1
    fi
    
    local success_count=0
    local failure_count=0
    
    while IFS= read -r username; do
        # Ignorer les lignes vides et les commentaires
        [[ -z "$username" || "$username" =~ ^# ]] && continue
        
        log_action "Traitement de l'utilisateur : $username"
        
        case "$operation" in
            "clear")
                if enterprise_clear_password "$username" "$admin_username" "$admin_password" "false"; then
                    ((success_count++))
                else
                    ((failure_count++))
                fi
                ;;
            "check")
                check_password_status "$username"
                ;;
            *)
                log_action "❌ Opération inconnue : $operation"
                return 1
                ;;
        esac
        
        # Petit délai entre les opérations
        sleep 1
        
    done < "$users_file"
    
    log_action "Opérations en lot terminées - Succès : $success_count, Échecs : $failure_count"
    audit_log "OPÉRATION_EN_LOT_TERMINÉE opération : $operation, succès : $success_count, échecs : $failure_count"
}

# Application des politiques de mots de passe
enforce_password_policies() {
    log_action "Application des politiques de mots de passe d'entreprise"
    
    # Obtenir tous les utilisateurs (excluant les utilisateurs système)
    local users=$(dscl . -list /Users | grep -v '^_' | grep -v '^root' | grep -v '^daemon' | grep -v '^nobody')
    
    for username in $users; do
        local uid=$(dscl . -read "/Users/$username" UniqueID 2>/dev/null | awk '{print $2}')
        
        # Ignorer les utilisateurs système (UID < 500)
        if [[ "$uid" -lt 500 ]]; then
            continue
        fi
        
        log_action "Application de la politique de mot de passe pour l'utilisateur : $username"
        
        # Appliquer la politique de mot de passe d'entreprise
        local min_length="${MIN_PASSWORD_LENGTH:-$DEFAULT_MIN_PASSWORD_LENGTH}"
        local expiry_days="${PASSWORD_EXPIRY_DAYS:-$DEFAULT_PASSWORD_EXPIRY_DAYS}"
        local max_attempts="${MAX_FAILED_ATTEMPTS:-$DEFAULT_MAX_FAILED_ATTEMPTS}"
        
        pwpolicy -u "$username" -setpolicy "minChars=$min_length requiresAlpha requiresNumeric requiresMixedCase requiresSymbol passwordCannotBeName maxMinutesUntilChangePassword=$((expiry_days * 24 * 60)) maxFailedLoginAttempts=$max_attempts" 2>/dev/null || true
        
    done
    
    log_action "Application des politiques de mots de passe terminée"
}

# Envoyer une notification de sécurité
send_security_notification() {
    local username="$1"
    local event_type="$2"
    
    # Ceci s'intégrerait avec votre système de notification
    # Pour l'instant, enregistrer simplement l'événement
    audit_log "NOTIFICATION_SÉCURITÉ envoyée pour l'utilisateur : $username, événement : $event_type"
}

# Fonction principale de gestion des mots de passe
main() {
    local action="${1:-status}"
    local username="${2}"
    local admin_username="${3}"
    local admin_password="${4}"
    
    log_action "=== Gestion des Mots de Passe MacFleet Démarrée ==="
    
    case "$action" in
        "clear")
            if [[ -z "$username" || -z "$admin_username" || -z "$admin_password" ]]; then
                echo "Usage : $0 clear <nom_utilisateur> <nom_utilisateur_admin> <mot_de_passe_admin>"
                exit 1
            fi
            load_password_config
            enterprise_clear_password "$username" "$admin_username" "$admin_password"
            ;;
        "clear-force")
            if [[ -z "$username" || -z "$admin_username" || -z "$admin_password" ]]; then
                echo "Usage : $0 clear-force <nom_utilisateur> <nom_utilisateur_admin> <mot_de_passe_admin>"
                exit 1
            fi
            load_password_config
            enterprise_clear_password "$username" "$admin_username" "$admin_password" "true"
            ;;
        "check")
            if [[ -z "$username" ]]; then
                echo "Usage : $0 check <nom_utilisateur>"
                exit 1
            fi
            check_password_status "$username"
            ;;
        "bulk")
            local operation="$2"
            local users_file="$3"
            shift 3
            admin_username="$1"
            admin_password="$2"
            load_password_config
            bulk_password_operations "$operation" "$users_file" "$admin_username" "$admin_password"
            ;;
        "enforce-policies")
            load_password_config
            enforce_password_policies
            ;;
        "status")
            echo "Système de Gestion des Mots de Passe MacFleet"
            echo "Commandes disponibles :"
            echo "  clear <utilisateur> <admin_utilisateur> <admin_pass>  - Effacer le mot de passe utilisateur"
            echo "  clear-force <utilisateur> <admin_utilisateur> <admin_pass>  - Forcer l'effacement (utilisateurs admin)"
            echo "  check <utilisateur>                            - Vérifier le statut du mot de passe"
            echo "  bulk <opération> <fichier_utilisateurs> <admin_utilisateur> <admin_pass>  - Opérations en lot"
            echo "  enforce-policies                        - Appliquer les politiques de mots de passe"
            echo "  status                                  - Afficher cette aide"
            ;;
        *)
            echo "❌ Action inconnue : $action"
            echo "Utilisez '$0 status' pour les commandes disponibles"
            exit 1
            ;;
    esac
    
    log_action "=== Gestion des Mots de Passe MacFleet Terminée ==="
}

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

Configuration de Gestion des Mots de Passe

Créer un fichier de configuration pour les politiques de mots de passe d'entreprise :

#!/bin/bash

# Créer un fichier de configuration de gestion des mots de passe
create_password_config() {
    local config_dir="/etc/macfleet"
    local config_file="$config_dir/password_config.conf"
    
    # Créer le répertoire s'il n'existe pas
    sudo mkdir -p "$config_dir"
    
    # Créer le fichier de configuration
    sudo tee "$config_file" > /dev/null << 'EOF'
# Configuration de Gestion des Mots de Passe MacFleet

# Paramètres de politique de mot de passe
MIN_PASSWORD_LENGTH=12
PASSWORD_EXPIRY_DAYS=90
MAX_FAILED_ATTEMPTS=5
LOCKOUT_DURATION=30

# Exigences de sécurité
REQUIRE_UPPERCASE=true
REQUIRE_LOWERCASE=true
REQUIRE_NUMBERS=true
REQUIRE_SPECIAL_CHARS=true
PREVENT_COMMON_PASSWORDS=true

# Paramètres opérationnels
ENABLE_AUDIT_LOGGING=true
ENABLE_SECURITY_NOTIFICATIONS=true
ENABLE_AUTOMATIC_BACKUP=true
BACKUP_RETENTION_DAYS=365

# Considérations FileVault
WARN_FILEVAULT_USERS=true
REQUIRE_FORCE_FOR_FILEVAULT=true

# Protection des utilisateurs admin
WARN_ADMIN_USERS=true
REQUIRE_FORCE_FOR_ADMIN=true

# Paramètres de conformité
ENABLE_COMPLIANCE_REPORTING=true
COMPLIANCE_REPORT_INTERVAL=7200  # 2 heures
SEND_COMPLIANCE_ALERTS=true
EOF

    echo "Configuration de gestion des mots de passe créée dans : $config_file"
    echo "Veuillez réviser et modifier les paramètres selon vos politiques de sécurité"
}

create_password_config

Considérations de Sécurité et Bonnes Pratiques

Compatibilité FileVault

#!/bin/bash

# Vérifier la compatibilité FileVault avant les opérations de mot de passe
check_filevault_compatibility() {
    local username="$1"
    
    echo "=== Vérification de Compatibilité FileVault ==="
    
    # Vérifier si FileVault est activé
    if fdesetup status | grep -q "FileVault is On"; then
        echo "✅ FileVault est activé"
        
        # Vérifier si l'utilisateur est un utilisateur FileVault
        local filevault_users=$(fdesetup list)
        if echo "$filevault_users" | grep -q "$username"; then
            echo "⚠️  L'utilisateur '$username' est un utilisateur FileVault"
            echo "   L'effacement du mot de passe peut affecter l'accès au chiffrement du disque"
            echo "   Considérez les éléments suivants avant de procéder :"
            echo "   - S'assurer que d'autres utilisateurs FileVault existent"
            echo "   - Avoir la clé de récupération disponible"
            echo "   - L'utilisateur peut avoir besoin de réactiver FileVault après la réinitialisation du mot de passe"
            return 1
        else
            echo "✅ L'utilisateur '$username' n'est pas un utilisateur FileVault"
            return 0
        fi
    else
        echo "ℹ️  FileVault n'est pas activé"
        return 0
    fi
}

check_filevault_compatibility

Audit et Conformité

#!/bin/bash

# Générer un rapport d'audit complet
generate_audit_report() {
    local report_file="/var/log/macfleet_password_audit_$(date +%Y%m%d_%H%M%S).txt"
    
    {
        echo "Rapport d'Audit de Gestion des Mots de Passe MacFleet"
        echo "Généré : $(date)"
        echo "Appareil : $(hostname)"
        echo "====================================="
        echo ""
        
        echo "Utilisateurs Système (UID >= 500) :"
        dscl . -list /Users | while read username; do
            local uid=$(dscl . -read "/Users/$username" UniqueID 2>/dev/null | awk '{print $2}')
            if [[ "$uid" -ge 500 ]]; then
                local real_name=$(dscl . -read "/Users/$username" RealName 2>/dev/null | cut -d' ' -f2-)
                local is_admin=""
                if dscl . -read "/Groups/admin" GroupMembership 2>/dev/null | grep -q "$username"; then
                    is_admin=" (Admin)"
                fi
                echo "- $username (UID : $uid)$is_admin - $real_name"
            fi
        done
        echo ""
        
        echo "Statut FileVault :"
        fdesetup status
        if fdesetup status | grep -q "FileVault is On"; then
            echo "Utilisateurs FileVault :"
            fdesetup list
        fi
        echo ""
        
        echo "Activités Récentes de Gestion des Mots de Passe :"
        if [[ -f "$AUDIT_FILE" ]]; then
            tail -20 "$AUDIT_FILE"
        else
            echo "Aucun journal d'audit trouvé"
        fi
        
    } > "$report_file"
    
    echo "Rapport d'audit généré : $report_file"
}

generate_audit_report

Intégration avec la Gestion MacFleet

#!/bin/bash

# Intégration de gestion des mots de passe MacFleet
macfleet_password_integration() {
    echo "=== Intégration de Gestion des Mots de Passe MacFleet ==="
    
    # Informations de l'appareil
    local device_id=$(system_profiler SPHardwareDataType | grep "Hardware UUID" | awk '{print $3}')
    local hostname=$(hostname)
    local macos_version=$(sw_vers -productVersion)
    
    # Obtenir les statistiques de comptes utilisateur
    local total_users=$(dscl . -list /Users | grep -v '^_' | grep -v '^root' | grep -v '^daemon' | grep -v '^nobody' | wc -l)
    local admin_users=$(dscl . -read "/Groups/admin" GroupMembership 2>/dev/null | wc -w)
    
    # Statut FileVault
    local filevault_enabled=false
    local filevault_users=0
    if fdesetup status | grep -q "FileVault is On"; then
        filevault_enabled=true
        filevault_users=$(fdesetup list | wc -l)
    fi
    
    # Activités récentes de gestion des mots de passe
    local recent_activities=0
    if [[ -f "$AUDIT_FILE" ]]; then
        recent_activities=$(grep "$(date +%Y-%m-%d)" "$AUDIT_FILE" | wc -l)
    fi
    
    # Rapporter à l'API MacFleet
    local api_data='{
        "device_id": "'$device_id'",
        "hostname": "'$hostname'",
        "timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'",
        "macos_version": "'$macos_version'",
        "password_management": {
            "total_users": '$total_users',
            "admin_users": '$admin_users',
            "filevault_enabled": '$filevault_enabled',
            "filevault_users": '$filevault_users',
            "recent_activities": '$recent_activities'
        },
        "password_management_status": "actif"
    }'
    
    echo "Statut de gestion des mots de passe rapporté au système de gestion MacFleet"
    echo "ID Appareil : $device_id"
    echo "Total Utilisateurs : $total_users"
    echo "Utilisateurs Admin : $admin_users"
    echo "FileVault Activé : $filevault_enabled"
    echo "Activités Récentes : $recent_activities"
}

macfleet_password_integration

Notes de Sécurité Importantes

Avertissements de Sécurité

  • L'effacement de mot de passe crée des risques de sécurité - utilisez seulement quand nécessaire
  • Les utilisateurs FileVault nécessitent une considération spéciale - peut affecter le chiffrement du disque
  • Les utilisateurs admin nécessitent une prudence supplémentaire - peut compromettre la sécurité du système
  • Toujours créer des sauvegardes avant de faire des changements de mots de passe

Bonnes Pratiques

  • Utiliser sysadminctl plutôt que dscl pour une meilleure sécurité et des pistes d'audit
  • Implémenter des politiques de mots de passe fortes après l'effacement des mots de passe
  • Surveiller et auditer toutes les opérations de mots de passe
  • Tester sur des appareils pilotes avant le déploiement à l'échelle de la flotte

Considérations de Conformité

  • Documenter toutes les opérations de mots de passe pour les audits de sécurité
  • Maintenir des procédures de sauvegarde et de récupération
  • Évaluations de sécurité régulières des comptes utilisateur
  • Intégration avec les systèmes d'identité d'entreprise pour la gestion centralisée

Application de Politiques de Mots de Passe en Entreprise sur macOS

Appliquez des politiques de mots de passe de niveau entreprise et des standards de sécurité sur vos appareils MacFleet en utilisant des outils en ligne de commande complets et des frameworks de sécurité. Ce tutoriel couvre l'implémentation de politiques de mots de passe, la surveillance de la conformité et les systèmes d'application automatisés.

Comprendre la Sécurité des Mots de Passe sur macOS

macOS fournit plusieurs couches de sécurité pour les mots de passe :

  • Politiques de Mots de Passe - Exigences de complexité, longueur et rotation
  • Sécurité de Verrouillage d'Écran - Verrouillage automatique et exigences de déverrouillage
  • Gestion de Secure Token - Support FileVault et chiffrement
  • Sécurité des Comptes - Privilèges utilisateur et contrôles d'accès

Configuration des Politiques de Mots de Passe

Exigences de Base pour les Mots de Passe

#!/bin/bash

# Définir une politique de mots de passe de base avec pwpolicy
configure_password_policy() {
    # Configurer les exigences de complexité des mots de passe
    sudo pwpolicy -a diradmin -u $USER -setpolicy "minChars=8 requiresAlpha requiresNumeric"
    
    # Définir l'historique des mots de passe (empêcher la réutilisation des 5 derniers)
    sudo pwpolicy -a diradmin -u $USER -setpolicy "usingHistory=5"
    
    # Définir l'expiration des mots de passe (90 jours)
    sudo pwpolicy -a diradmin -u $USER -setpolicy "maxMinutesUntilChangePassword=129600"
    
    echo "Politique de mots de passe de base configurée avec succès"
}

configure_password_policy

Paramètres de Sécurité Avancés

#!/bin/bash

# Configurer les paramètres avancés de mots de passe et de sécurité
configure_advanced_security() {
    echo "=== Configuration de Sécurité Avancée ==="
    
    # Activer l'exigence de mot de passe pour le réveil
    osascript -e 'tell application "System Events" to set require password to wake of security preferences to true'
    
    # Définir l'exigence immédiate de mot de passe
    defaults write com.apple.screensaver askForPassword -int 1
    defaults write com.apple.screensaver askForPasswordDelay -int 0
    
    # Configurer la politique de verrouillage de compte
    sudo pwpolicy -a diradmin -setpolicy "maxFailedLoginAttempts=5"
    
    # Activer la déconnexion automatique après inactivité
    sudo defaults write /Library/Preferences/.GlobalPreferences com.apple.autologout.AutoLogOutDelay -int 3600
    
    echo "Paramètres de sécurité avancés configurés"
}

configure_advanced_security

Application du Verrouillage d'Écran

Verrouillage Automatique d'Écran

#!/bin/bash

# Configurer les paramètres de verrouillage automatique d'écran
configure_screen_lock() {
    local lock_delay="${1:-300}" # Par défaut 5 minutes
    
    echo "Configuration du verrouillage d'écran avec un délai de ${lock_delay} secondes"
    
    # Définir le temps d'activation de l'économiseur d'écran
    defaults -currentHost write com.apple.screensaver idleTime -int "$lock_delay"
    
    # Activer l'exigence de mot de passe pour l'économiseur d'écran
    defaults write com.apple.screensaver askForPassword -int 1
    defaults write com.apple.screensaver askForPasswordDelay -int 0
    
    # Configurer les paramètres d'économie d'énergie
    sudo pmset -a displaysleep 5    # Mise en veille de l'écran après 5 minutes
    sudo pmset -a sleep 30          # Mise en veille du système après 30 minutes
    
    # Arrêter les préférences d'économiseur d'écran pour appliquer les changements
    killall ScreenSaverEngine 2>/dev/null || true
    
    echo "Verrouillage d'écran configuré avec succès"
}

# Utilisation : configure_screen_lock [délai_en_secondes]
configure_screen_lock 300

Application de Verrouillage Immédiat

#!/bin/bash

# Forcer le verrouillage immédiat de l'écran
force_screen_lock() {
    echo "Forçage du verrouillage immédiat de l'écran..."
    
    # Méthodes multiples pour assurer le verrouillage
    /System/Library/CoreServices/Menu\ Extras/User.menu/Contents/Resources/CGSession -suspend
    
    # Méthode alternative utilisant pmset
    pmset displaysleepnow
    
    # Activer l'économiseur d'écran comme solution de secours
    /System/Library/Frameworks/ScreenSaver.framework/Resources/ScreenSaverEngine.app/Contents/MacOS/ScreenSaverEngine -background &
    
    echo "Écran verrouillé avec succès"
}

force_screen_lock

Application de la Complexité des Mots de Passe

Validation de la Complexité des Mots de Passe

#!/bin/bash

# Valider la complexité des mots de passe
validate_password_complexity() {
    local password="$1"
    local min_length=8
    local errors=0
    
    echo "=== Validation de la Complexité des Mots de Passe ==="
    
    # Vérifier la longueur minimale
    if [[ ${#password} -lt $min_length ]]; then
        echo "❌ Le mot de passe doit contenir au moins $min_length caractères"
        ((errors++))
    else
        echo "✅ Exigence de longueur respectée"
    fi
    
    # Vérifier la présence d'une lettre majuscule
    if [[ ! "$password" =~ [A-Z] ]]; then
        echo "❌ Le mot de passe doit contenir au moins une lettre majuscule"
        ((errors++))
    else
        echo "✅ Lettre majuscule trouvée"
    fi
    
    # Vérifier la présence d'une lettre minuscule
    if [[ ! "$password" =~ [a-z] ]]; then
        echo "❌ Le mot de passe doit contenir au moins une lettre minuscule"
        ((errors++))
    else
        echo "✅ Lettre minuscule trouvée"
    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"
        ((errors++))
    else
        echo "✅ Chiffre trouvé"
    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"
        ((errors++))
    else
        echo "✅ Caractère spécial trouvé"
    fi
    
    # Vérifier les motifs courants
    if [[ "$password" =~ (123|abc|password|qwerty) ]]; then
        echo "❌ Le mot de passe contient des motifs courants"
        ((errors++))
    else
        echo "✅ Aucun motif courant détecté"
    fi
    
    if [[ $errors -eq 0 ]]; then
        echo "✅ Le mot de passe respecte toutes les exigences de complexité"
        return 0
    else
        echo "❌ Le mot de passe a échoué à $errors vérifications de complexité"
        return 1
    fi
}

# Exemple d'utilisation (ne pas utiliser en production avec de vrais mots de passe)
# validate_password_complexity "MotDePasseTest123!"

Génération de Mots de Passe

#!/bin/bash

# Générer des mots de passe sécurisés
generate_secure_password() {
    local length="${1:-12}"
    local include_symbols="${2:-true}"
    
    echo "=== Génération de Mots de Passe Sécurisés ==="
    
    if [[ "$include_symbols" == "true" ]]; then
        # Générer un mot de passe avec des symboles
        local charset='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*'
    else
        # Générer un mot de passe alphanumérique
        local charset='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
    fi
    
    # Générer un mot de passe aléatoire
    local password=$(openssl rand -base64 32 | tr -d "=+/" | cut -c1-${length})
    
    # Assurer les exigences de complexité
    password="${password:0:$((length-4))}A1@z"
    
    echo "Longueur du mot de passe généré : ${#password}"
    echo "Complexité du mot de passe vérifiée"
    
    # Valider le mot de passe généré
    if validate_password_complexity "$password"; then
        echo "✅ Le mot de passe généré respecte toutes les exigences"
    fi
}

generate_secure_password 12 true

Gestion des Comptes Utilisateur

Réinitialisation et Gestion des Mots de Passe

#!/bin/bash

# Gestion des mots de passe des comptes utilisateur
manage_user_passwords() {
    local username="$1"
    local action="$2"
    
    echo "=== Gestion des Mots de Passe Utilisateur ==="
    echo "Gestion du mot de passe pour l'utilisateur : $username"
    
    case "$action" in
        "reset")
            # Forcer la réinitialisation du mot de passe à la prochaine connexion
            sudo pwpolicy -a diradmin -u "$username" -setpolicy "newPasswordRequired=1"
            echo "Réinitialisation du mot de passe requise pour $username à la prochaine connexion"
            ;;
        "expire")
            # Faire expirer le mot de passe immédiatement
            sudo pwpolicy -a diradmin -u "$username" -setpolicy "passwordLastSetTime=0"
            echo "Mot de passe expiré pour $username"
            ;;
        "unlock")
            # Déverrouiller le compte après des tentatives échouées
            sudo pwpolicy -a diradmin -u "$username" -clearfailedlogins
            echo "Compte déverrouillé pour $username"
            ;;
        "status")
            # Vérifier le statut du mot de passe
            sudo pwpolicy -a diradmin -u "$username" -getpolicy
            ;;
        *)
            echo "Usage : manage_user_passwords <nom_utilisateur> <reset|expire|unlock|status>"
            return 1
            ;;
    esac
}

# Exemple d'utilisation
# manage_user_passwords "johndoe" "status"

Gestion des Secure Tokens

#!/bin/bash

# Ajouter un secure token au compte utilisateur
add_secure_token() {
    local admin_user="$1"
    local admin_password="$2"
    local target_user="$3"
    local target_password="$4"
    
    echo "=== Gestion des Secure Tokens ==="
    
    # Vérifier la compatibilité de la version macOS
    local macos_version=$(sw_vers -productVersion)
    echo "Version macOS : $macos_version"
    
    # Vérifier si l'utilisateur cible a déjà un secure token
    if sysadminctl -secureTokenStatus "$target_user" 2>&1 | grep -q "ENABLED"; then
        echo "✅ $target_user a déjà un SecureToken"
        return 0
    fi
    
    # Vérifier si l'utilisateur admin a un secure token
    if sysadminctl -secureTokenStatus "$admin_user" 2>&1 | grep -q "DISABLED"; then
        echo "❌ L'utilisateur admin $admin_user n'a pas de SecureToken"
        return 1
    fi
    
    echo "Ajout du SecureToken à $target_user..."
    
    # Ajouter le secure token
    if sysadminctl -adminUser "$admin_user" \
                   -adminPassword "$admin_password" \
                   -secureTokenOn "$target_user" \
                   -password "$target_password"; then
        echo "✅ SecureToken ajouté avec succès à $target_user"
    else
        echo "❌ Échec de l'ajout du SecureToken à $target_user"
        return 1
    fi
}

# Exemple d'utilisation (remplacer par les vraies informations d'identification dans un environnement sécurisé)
# add_secure_token "admin" "mot_passe_admin" "utilisateur" "mot_passe_utilisateur"

Système de Gestion de Mots de Passe d'Entreprise

#!/bin/bash

# Système de Gestion de Mots de Passe d'Entreprise MacFleet
# Application et surveillance complètes des politiques de mots de passe

# Configuration
LOG_FILE="/var/log/macfleet_password_security.log"
POLICY_CONFIG="/etc/macfleet/password_policy.conf"
COMPLIANCE_REPORT="/var/log/macfleet_password_compliance.json"

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

# Charger la configuration de politique de mots de passe
load_policy_config() {
    if [[ -f "$POLICY_CONFIG" ]]; then
        source "$POLICY_CONFIG"
    else
        # Valeurs par défaut
        MIN_PASSWORD_LENGTH=8
        MAX_PASSWORD_AGE=90
        PASSWORD_HISTORY=5
        MAX_FAILED_ATTEMPTS=5
        LOCK_TIMEOUT=300
        COMPLEXITY_REQUIRED=true
    fi
}

# Vérifier la conformité des mots de passe pour tous les utilisateurs
check_password_compliance() {
    log_action "Début de la vérification de conformité des mots de passe"
    
    local compliance_data='{"timestamp":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","users":[]}'
    local non_compliant_count=0
    
    # Obtenir tous les utilisateurs locaux
    local users=$(dscl . list /Users | grep -v '^_' | grep -v 'daemon\|nobody\|root')
    
    while IFS= read -r username; do
        if [[ -n "$username" ]]; then
            log_action "Vérification de la conformité pour l'utilisateur : $username"
            
            local user_data='{"username":"'$username'","compliant":true,"issues":[]}'
            local issues=()
            
            # Vérifier l'âge du mot de passe
            local last_change=$(dscl . read "/Users/$username" passwordPolicyOptions | grep -o 'passwordLastSetTime</key><real>[0-9.]*' | cut -d'>' -f2 || echo "0")
            if [[ -n "$last_change" && "$last_change" != "0" ]]; then
                local age_days=$(( ($(date +%s) - ${last_change%.*}) / 86400 ))
                if [[ $age_days -gt $MAX_PASSWORD_AGE ]]; then
                    issues+=("Mot de passe expiré ($age_days jours)")
                fi
            fi
            
            # Vérifier le statut de verrouillage du compte
            local failed_attempts=$(dscl . read "/Users/$username" | grep -c "authenticationHint" || echo "0")
            
            # Vérifier le statut du secure token
            if ! sysadminctl -secureTokenStatus "$username" 2>&1 | grep -q "ENABLED"; then
                issues+=("Pas de SecureToken")
            fi
            
            # Mettre à jour les données de conformité
            if [[ ${#issues[@]} -gt 0 ]]; then
                user_data='{"username":"'$username'","compliant":false,"issues":["'$(IFS='","'; echo "${issues[*]}")'"]}' 
                ((non_compliant_count++))
            fi
            
            # Ajouter au rapport de conformité
            compliance_data=$(echo "$compliance_data" | jq --argjson user "$user_data" '.users += [$user]')
        fi
    done <<< "$users"
    
    # Sauvegarder le rapport de conformité
    echo "$compliance_data" | jq . > "$COMPLIANCE_REPORT"
    
    log_action "Vérification de conformité terminée : $non_compliant_count utilisateurs non conformes trouvés"
    
    if [[ $non_compliant_count -gt 0 ]]; then
        log_action "⚠️ Problèmes de conformité des mots de passe détectés"
        return 1
    else
        log_action "✅ Tous les utilisateurs sont conformes aux mots de passe"
        return 0
    fi
}

# Appliquer les politiques de mots de passe
enforce_password_policies() {
    log_action "Début de l'application des politiques de mots de passe"
    
    # Configurer les politiques de mots de passe à l'échelle du système
    log_action "Application des politiques de mots de passe à l'échelle du système"
    
    # Définir les exigences de complexité des mots de passe
    if [[ "$COMPLEXITY_REQUIRED" == "true" ]]; then
        sudo pwpolicy -a diradmin -setglobalpolicy "minChars=$MIN_PASSWORD_LENGTH requiresAlpha requiresNumeric"
        log_action "Exigences de complexité des mots de passe définies"
    fi
    
    # Configurer le verrouillage de compte
    sudo pwpolicy -a diradmin -setglobalpolicy "maxFailedLoginAttempts=$MAX_FAILED_ATTEMPTS"
    log_action "Politique de verrouillage de compte définie à $MAX_FAILED_ATTEMPTS tentatives échouées"
    
    # Configurer l'historique des mots de passe
    sudo pwpolicy -a diradmin -setglobalpolicy "usingHistory=$PASSWORD_HISTORY"
    log_action "Historique des mots de passe défini à $PASSWORD_HISTORY mots de passe précédents"
    
    # Configurer le verrouillage d'écran
    defaults write com.apple.screensaver askForPassword -int 1
    defaults write com.apple.screensaver askForPasswordDelay -int 0
    log_action "Exigence de mot de passe pour le verrouillage d'écran activée"
    
    # Définir le verrouillage automatique d'écran
    defaults -currentHost write com.apple.screensaver idleTime -int "$LOCK_TIMEOUT"
    log_action "Verrouillage automatique d'écran défini à $LOCK_TIMEOUT secondes"
}

# Générer un rapport de conformité des mots de passe
generate_compliance_report() {
    log_action "Génération du rapport de conformité des mots de passe"
    
    if [[ -f "$COMPLIANCE_REPORT" ]]; then
        local total_users=$(jq '.users | length' "$COMPLIANCE_REPORT")
        local compliant_users=$(jq '.users | map(select(.compliant == true)) | length' "$COMPLIANCE_REPORT")
        local non_compliant_users=$(jq '.users | map(select(.compliant == false)) | length' "$COMPLIANCE_REPORT")
        
        echo "=== Rapport de Conformité des Mots de Passe ==="
        echo "Rapport Généré : $(jq -r '.timestamp' "$COMPLIANCE_REPORT")"
        echo "Total des Utilisateurs : $total_users"
        echo "Utilisateurs Conformes : $compliant_users"
        echo "Utilisateurs Non Conformes : $non_compliant_users"
        echo "Taux de Conformité : $(( (compliant_users * 100) / total_users ))%"
        
        if [[ $non_compliant_users -gt 0 ]]; then
            echo ""
            echo "Utilisateurs Non Conformes :"
            jq -r '.users[] | select(.compliant == false) | "- " + .username + ": " + (.issues | join(", "))' "$COMPLIANCE_REPORT"
        fi
    else
        echo "Aucun rapport de conformité trouvé. Exécutez d'abord la vérification de conformité."
    fi
}

# Tâches automatisées de sécurité des mots de passe
run_security_maintenance() {
    log_action "=== Début de la maintenance automatisée de sécurité des mots de passe ==="
    
    # Charger la configuration
    load_policy_config
    
    # Vérifier la conformité
    check_password_compliance
    
    # Appliquer les politiques
    enforce_password_policies
    
    # Générer le rapport
    generate_compliance_report
    
    log_action "=== Maintenance de sécurité des mots de passe terminée ==="
}

# Exécution principale
main() {
    local action="${1:-maintenance}"
    
    case "$action" in
        "compliance")
            load_policy_config
            check_password_compliance
            ;;
        "enforce")
            load_policy_config
            enforce_password_policies
            ;;
        "report")
            generate_compliance_report
            ;;
        "maintenance")
            run_security_maintenance
            ;;
        *)
            echo "Usage : $0 [compliance|enforce|report|maintenance]"
            echo "  compliance - Vérifier la conformité des mots de passe pour tous les utilisateurs"
            echo "  enforce    - Appliquer les politiques de mots de passe"
            echo "  report     - Générer le rapport de conformité"
            echo "  maintenance - Exécuter le cycle de maintenance complet (par défaut)"
            exit 1
            ;;
    esac
}

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

Fichier de Configuration de Politique de Mots de Passe

Créer un fichier de configuration pour les politiques de mots de passe :

#!/bin/bash

# Créer la configuration de politique de mots de passe
create_policy_config() {
    local config_dir="/etc/macfleet"
    local config_file="$config_dir/password_policy.conf"
    
    # Créer le répertoire s'il n'existe pas
    sudo mkdir -p "$config_dir"
    
    # Créer le fichier de configuration
    sudo tee "$config_file" > /dev/null << 'EOF'
# Configuration de Politique de Mots de Passe MacFleet

# Exigences des Mots de Passe
MIN_PASSWORD_LENGTH=8
MAX_PASSWORD_LENGTH=128
REQUIRE_UPPERCASE=true
REQUIRE_LOWERCASE=true
REQUIRE_NUMBERS=true
REQUIRE_SPECIAL_CHARS=true

# Rotation des Mots de Passe
MAX_PASSWORD_AGE=90          # Jours avant expiration du mot de passe
PASSWORD_HISTORY=5           # Nombre de mots de passe précédents à mémoriser
EXPIRATION_WARNING_DAYS=14   # Jours avant expiration pour avertir l'utilisateur

# Sécurité des Comptes
MAX_FAILED_ATTEMPTS=5        # Tentatives de connexion échouées avant verrouillage
LOCKOUT_DURATION=1800        # Durée de verrouillage du compte en secondes
AUTO_UNLOCK=true             # Déverrouillage automatique après la durée de verrouillage

# Sécurité d'Écran
LOCK_TIMEOUT=300             # Délai de verrouillage d'écran en secondes
IMMEDIATE_LOCK=true          # Exiger le mot de passe immédiatement après verrouillage
SCREEN_SAVER_TIMEOUT=600     # Délai d'activation de l'économiseur d'écran

# Conformité
COMPLEXITY_REQUIRED=true     # Forcer la complexité des mots de passe
SECURE_TOKEN_REQUIRED=true   # Exiger SecureToken pour tous les utilisateurs
REGULAR_AUDITS=true          # Activer les audits de conformité réguliers
AUDIT_FREQUENCY=7            # Jours entre les audits de conformité

# Journalisation
ENABLE_LOGGING=true          # Activer la journalisation des événements de sécurité
LOG_LEVEL="INFO"             # Niveau de journalisation : DEBUG, INFO, WARN, ERROR
LOG_RETENTION=30             # Jours de rétention des fichiers journaux
EOF

    echo "Configuration de politique de mots de passe créée à : $config_file"
}

create_policy_config

Intégration avec la Gestion MacFleet

#!/bin/bash

# Intégration de gestion de mots de passe MacFleet
macfleet_password_integration() {
    echo "=== Intégration de Gestion de Mots de Passe MacFleet ==="
    
    # Enregistrement d'appareil
    local device_id=$(system_profiler SPHardwareDataType | grep "Hardware UUID" | awk '{print $3}')
    local hostname=$(hostname)
    
    echo "ID d'Appareil : $device_id"
    echo "Nom d'Hôte : $hostname"
    
    # Rapport à l'API MacFleet (placeholder)
    local api_endpoint="https://api.macfleet.com/devices/$device_id/security"
    local report_data='{
        "device_id": "'$device_id'",
        "hostname": "'$hostname'",
        "timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'",
        "password_policy_status": "enforced",
        "compliance_check": "'$(date +%s)'",
        "security_level": "enterprise"
    }'
    
    echo "Statut de sécurité rapporté à MacFleet"
}

macfleet_password_integration

Notes de Sécurité Importantes

Stockage et Manipulation des Mots de Passe

  • Ne jamais journaliser les vrais mots de passe dans les scripts ou les journaux
  • Utiliser une gestion sécurisée des informations d'identification pour les mots de passe administratifs
  • Implémenter un chiffrement approprié pour toute donnée d'authentification stockée
  • Audits de sécurité réguliers des politiques de mots de passe et de la conformité

Meilleures Pratiques

  • Tester les politiques sur des appareils de développement avant le déploiement de flotte
  • Déploiement progressif des nouvelles exigences de mots de passe
  • Communication utilisateur sur les changements de politique
  • Procédures d'urgence pour les verrouillages de compte et réinitialisations de mots de passe

Surveillance et Conformité

  • Audits réguliers de la conformité des mots de passe sur la flotte
  • Alertes automatisées pour les violations de politique
  • Tableau de bord de rapports pour le statut de sécurité
  • Intégration avec les systèmes de gestion d'identité d'entreprise

Ce système d'application de mots de passe d'entreprise fournit une gestion de sécurité complète pour les appareils MacFleet tout en maintenant l'utilisabilité et la conformité aux standards de sécurité d'entreprise.

Gestion Entreprise de Changement de Mot de Passe sur macOS

Gérez de manière sécurisée les opérations de changement de mot de passe dans votre déploiement MacFleet avec des contrôles de sécurité de niveau entreprise, l'application de politiques et des capacités d'audit complètes. Ce tutoriel transforme la commande de base dscl en une solution robuste de gestion des mots de passe adaptée aux environnements d'entreprise.

Comprendre la Gestion des Mots de Passe en Entreprise

Les opérations de changement de mot de passe en entreprise nécessitent des mesures de sécurité robustes au-delà des commandes de service d'annuaire de base :

  • Application de politiques de mot de passe pour garantir les standards de sécurité
  • Gestion sécurisée des identifiants pour prévenir l'exposition
  • Journalisation d'audit complète pour le suivi de conformité
  • Intégration d'authentification multi-facteurs pour une sécurité renforcée
  • Validation des privilèges pour assurer une autorisation appropriée
  • Synchronisation du trousseau pour une expérience utilisateur fluide

Opération de Changement de Mot de Passe de Base

Commande de Changement de Mot de Passe Basique

# Changement de mot de passe basique avec dscl
sudo dscl . -passwd /Users/nom_utilisateur mot_de_passe_actuel nouveau_mot_de_passe

Ceci utilise l'utilitaire en ligne de commande du service d'annuaire (dscl) pour modifier les données d'annuaire utilisateur, spécifiquement le champ mot de passe.

Système de Gestion de Changement de Mot de Passe Entreprise

#!/bin/bash

# Système de Gestion de Changement de Mot de Passe Entreprise MacFleet
# Opérations de changement de mot de passe sécurisées avec contrôles entreprise complets

# Configuration
SCRIPT_NAME="Gestionnaire de Changement de Mot de Passe MacFleet"
VERSION="1.0.0"
LOG_FILE="/var/log/macfleet_password_operations.log"
AUDIT_LOG="/var/log/macfleet_password_audit.log"
POLICY_FILE="/etc/macfleet/password_policy.conf"
TEMP_DIR="/tmp/macfleet_password"
SECURE_LOG_RETENTION_DAYS=365
MAX_LOGIN_ATTEMPTS=3
PASSWORD_HISTORY_COUNT=12
LOCKOUT_DURATION=1800  # 30 minutes
MIN_PASSWORD_LENGTH=12
MAX_PASSWORD_LENGTH=128
COMPLEXITY_REQUIREMENTS=true
BUSINESS_HOURS_START=9
BUSINESS_HOURS_END=17
EMERGENCY_CONTACTS=("securite@entreprise.com" "admin@entreprise.com")

# Exigences de complexité des mots de passe
REQUIRE_UPPERCASE=true
REQUIRE_LOWERCASE=true
REQUIRE_NUMBERS=true
REQUIRE_SPECIAL_CHARS=true
FORBIDDEN_PATTERNS=("password" "motdepasse" "123456" "qwerty" "admin" "root")

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

# Définir les permissions sécurisées
chmod 700 "$TEMP_DIR"
touch "$LOG_FILE" && chmod 640 "$LOG_FILE"
touch "$AUDIT_LOG" && chmod 600 "$AUDIT_LOG"

# 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_security_event() {
    local event_type="$1"
    local username="$2"
    local details="$3"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    local source_ip=$(who am i | awk '{print $5}' | tr -d '()')
    local session_id=$(who am i | awk '{print $2}')
    
    {
        echo "SECURITY_EVENT|$timestamp|$event_type|$username|$source_ip|$session_id|$details"
    } >> "$AUDIT_LOG"
    
    log_operation "SECURITY" "$event_type pour l'utilisateur $username : $details"
}

# Vérifier si l'utilisateur existe
user_exists() {
    local username="$1"
    dscl . -read "/Users/$username" &>/dev/null
    return $?
}

# Vérifier si l'utilisateur est un compte système
is_system_account() {
    local username="$1"
    local uid=$(dscl . -read "/Users/$username" UniqueID 2>/dev/null | awk '{print $2}')
    
    # Les comptes système ont typiquement UID < 500
    if [[ -n "$uid" && $uid -lt 500 ]]; then
        return 0
    fi
    
    # Vérifier les comptes système communs
    local system_accounts=("root" "daemon" "nobody" "_www" "_mysql" "_postgres")
    for sys_account in "${system_accounts[@]}"; do
        if [[ "$username" == "$sys_account" ]]; then
            return 0
        fi
    done
    
    return 1
}

# Valider que l'utilisateur actuel a la permission de changer le mot de passe
validate_permission() {
    local target_username="$1"
    local current_user=$(whoami)
    
    # Root peut changer n'importe quel mot de passe
    if [[ "$current_user" == "root" ]]; then
        return 0
    fi
    
    # Les utilisateurs peuvent changer leur propre mot de passe
    if [[ "$current_user" == "$target_username" ]]; then
        return 0
    fi
    
    # Vérifier si l'utilisateur actuel est admin
    if dseditgroup -o checkmember -m "$current_user" admin &>/dev/null; then
        return 0
    fi
    
    log_security_event "PERMISSION_DENIED" "$target_username" "L'utilisateur $current_user a tenté un changement de mot de passe non autorisé"
    return 1
}

# Générer un mot de passe sécurisé aléatoire
generate_secure_password() {
    local length="${1:-16}"
    local password=""
    local attempts=0
    local max_attempts=10
    
    while [[ $attempts -lt $max_attempts ]]; do
        # Générer un mot de passe avec un jeu de caractères mixte
        password=$(openssl rand -base64 32 | tr -d "=+/" | cut -c1-"$length")
        
        # Ajouter des caractères spéciaux
        password="${password}$(openssl rand -base64 4 | tr -d "=+/" | tr 'A-Za-z0-9' '@#$%&*' | cut -c1-2)"
        
        # Valider que le mot de passe répond aux exigences
        if validate_password_complexity "$password"; then
            echo "$password"
            return 0
        fi
        
        ((attempts++))
    done
    
    log_operation "ERROR" "Échec de génération d'un mot de passe sécurisé après $max_attempts tentatives"
    return 1
}

# Valider la complexité du mot de passe
validate_password_complexity() {
    local password="$1"
    local length=${#password}
    
    # Vérifier les exigences de longueur
    if [[ $length -lt $MIN_PASSWORD_LENGTH ]]; then
        log_operation "WARNING" "Mot de passe trop court : $length < $MIN_PASSWORD_LENGTH"
        return 1
    fi
    
    if [[ $length -gt $MAX_PASSWORD_LENGTH ]]; then
        log_operation "WARNING" "Mot de passe trop long : $length > $MAX_PASSWORD_LENGTH"
        return 1
    fi
    
    if [[ "$COMPLEXITY_REQUIREMENTS" == "true" ]]; then
        # Vérifier les lettres majuscules
        if [[ "$REQUIRE_UPPERCASE" == "true" ]] && ! [[ "$password" =~ [A-Z] ]]; then
            log_operation "WARNING" "Mot de passe manque de lettres majuscules"
            return 1
        fi
        
        # Vérifier les lettres minuscules
        if [[ "$REQUIRE_LOWERCASE" == "true" ]] && ! [[ "$password" =~ [a-z] ]]; then
            log_operation "WARNING" "Mot de passe manque de lettres minuscules"
            return 1
        fi
        
        # Vérifier les chiffres
        if [[ "$REQUIRE_NUMBERS" == "true" ]] && ! [[ "$password" =~ [0-9] ]]; then
            log_operation "WARNING" "Mot de passe manque de chiffres"
            return 1
        fi
        
        # Vérifier les caractères spéciaux
        if [[ "$REQUIRE_SPECIAL_CHARS" == "true" ]] && ! [[ "$password" =~ [^a-zA-Z0-9] ]]; then
            log_operation "WARNING" "Mot de passe manque de caractères spéciaux"
            return 1
        fi
    fi
    
    # Vérifier les motifs interdits
    local password_lower=$(echo "$password" | tr '[:upper:]' '[:lower:]')
    for pattern in "${FORBIDDEN_PATTERNS[@]}"; do
        if [[ "$password_lower" == *"$pattern"* ]]; then
            log_operation "WARNING" "Mot de passe contient un motif interdit : $pattern"
            return 1
        fi
    done
    
    return 0
}

# Vérifier l'historique des mots de passe
check_password_history() {
    local username="$1"
    local new_password="$2"
    local history_file="/var/db/macfleet/password_history/$username"
    
    if [[ ! -f "$history_file" ]]; then
        return 0  # Pas d'historique, mot de passe acceptable
    fi
    
    # Hacher le nouveau mot de passe pour comparaison
    local new_hash=$(echo -n "$new_password" | shasum -a 256 | cut -d' ' -f1)
    
    # Vérifier contre les hachages stockés
    if grep -q "$new_hash" "$history_file"; then
        log_operation "WARNING" "Réutilisation de mot de passe détectée pour l'utilisateur $username"
        return 1
    fi
    
    return 0
}

# Stocker le mot de passe dans l'historique
store_password_history() {
    local username="$1"
    local password="$2"
    local history_dir="/var/db/macfleet/password_history"
    local history_file="$history_dir/$username"
    
    # Créer le répertoire s'il n'existe pas
    mkdir -p "$history_dir"
    chmod 700 "$history_dir"
    
    # Hacher le mot de passe
    local password_hash=$(echo -n "$password" | shasum -a 256 | cut -d' ' -f1)
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    
    # Ajouter à l'historique
    echo "$timestamp:$password_hash" >> "$history_file"
    chmod 600 "$history_file"
    
    # Maintenir le nombre d'historique
    if [[ $(wc -l < "$history_file") -gt $PASSWORD_HISTORY_COUNT ]]; then
        tail -n "$PASSWORD_HISTORY_COUNT" "$history_file" > "$history_file.tmp"
        mv "$history_file.tmp" "$history_file"
    fi
}

# Vérifier le mot de passe actuel
verify_current_password() {
    local username="$1"
    local current_password="$2"
    
    # Utiliser dscl pour vérifier le mot de passe
    if dscl . -authonly "$username" "$current_password" &>/dev/null; then
        return 0
    else
        log_security_event "AUTH_FAILURE" "$username" "Échec de vérification du mot de passe actuel"
        return 1
    fi
}

# Mettre à jour le mot de passe du trousseau
update_keychain_password() {
    local username="$1"
    local old_password="$2"
    local new_password="$3"
    
    log_operation "INFO" "Mise à jour du mot de passe du trousseau pour l'utilisateur $username"
    
    # Obtenir le répertoire home de l'utilisateur
    local home_dir=$(dscl . -read "/Users/$username" NFSHomeDirectory | awk '{print $2}')
    local keychain_path="$home_dir/Library/Keychains/login.keychain-db"
    
    if [[ -f "$keychain_path" ]]; then
        # Mettre à jour le mot de passe du trousseau
        if su "$username" -c "security unlock-keychain -p '$old_password' '$keychain_path' && security set-keychain-password -o '$old_password' -p '$new_password' '$keychain_path'" &>/dev/null; then
            log_operation "SUCCESS" "Mot de passe du trousseau mis à jour pour l'utilisateur $username"
            return 0
        else
            log_operation "WARNING" "Échec de mise à jour du mot de passe du trousseau pour l'utilisateur $username"
            return 1
        fi
    else
        log_operation "INFO" "Aucun trousseau trouvé pour l'utilisateur $username"
        return 0
    fi
}

# Fonction de changement de mot de passe entreprise
enterprise_change_password() {
    local username="$1"
    local current_password="$2"
    local new_password="$3"
    local force_change="${4:-false}"
    local bypass_history="${5:-false}"
    
    local operation_id=$(date +%s)
    log_operation "INFO" "Début de l'opération de changement de mot de passe [$operation_id] pour l'utilisateur : $username"
    
    # Valider que l'utilisateur existe
    if ! user_exists "$username"; then
        log_operation "ERROR" "L'utilisateur n'existe pas : $username"
        log_security_event "USER_NOT_FOUND" "$username" "Tentative de changement de mot de passe pour un utilisateur inexistant"
        return 1
    fi
    
    # Vérifier si c'est un compte système
    if is_system_account "$username"; then
        log_operation "ERROR" "Impossible de changer le mot de passe pour le compte système : $username"
        log_security_event "SYSTEM_ACCOUNT_ACCESS" "$username" "Tentative de changement de mot de passe sur un compte système"
        return 1
    fi
    
    # Valider les permissions
    if ! validate_permission "$username"; then
        log_operation "ERROR" "Permission refusée pour le changement de mot de passe : $username"
        return 1
    fi
    
    # Vérifier le mot de passe actuel (sauf si forcé)
    if [[ "$force_change" != "true" ]]; then
        if ! verify_current_password "$username" "$current_password"; then
            log_operation "ERROR" "Échec de vérification du mot de passe actuel pour l'utilisateur : $username"
            return 1
        fi
    fi
    
    # Valider la complexité du nouveau mot de passe
    if ! validate_password_complexity "$new_password"; then
        log_operation "ERROR" "Le nouveau mot de passe ne répond pas aux exigences de complexité pour l'utilisateur : $username"
        return 1
    fi
    
    # Vérifier l'historique des mots de passe (sauf si contourné)
    if [[ "$bypass_history" != "true" ]]; then
        if ! check_password_history "$username" "$new_password"; then
            log_operation "ERROR" "Réutilisation de mot de passe détectée pour l'utilisateur : $username"
            return 1
        fi
    fi
    
    # Créer des fichiers temporaires sécurisés
    local temp_log="$TEMP_DIR/change_password_${operation_id}.log"
    
    # Changer le mot de passe en utilisant dscl
    log_operation "INFO" "Exécution du changement de mot de passe pour l'utilisateur : $username"
    
    if [[ "$force_change" == "true" ]]; then
        # Changement forcé sans mot de passe actuel
        if dscl . -passwd "/Users/$username" "$new_password" 2>"$temp_log"; then
            local result=0
        else
            local result=1
        fi
    else
        # Changement normal avec vérification du mot de passe actuel
        if dscl . -passwd "/Users/$username" "$current_password" "$new_password" 2>"$temp_log"; then
            local result=0
        else
            local result=1
        fi
    fi
    
    # Vérifier le résultat
    if [[ $result -eq 0 ]]; then
        log_operation "SUCCESS" "Mot de passe changé avec succès [$operation_id] pour l'utilisateur : $username"
        log_security_event "PASSWORD_CHANGED" "$username" "Mot de passe changé avec succès"
        
        # Stocker dans l'historique des mots de passe
        store_password_history "$username" "$new_password"
        
        # Mettre à jour le trousseau si ce n'est pas un changement forcé
        if [[ "$force_change" != "true" ]]; then
            update_keychain_password "$username" "$current_password" "$new_password"
        fi
        
        # Nettoyer les fichiers temporaires de manière sécurisée
        shred -vfz -n 3 "$temp_log" 2>/dev/null || {
            rm -f "$temp_log"
        }
        
        return 0
    else
        log_operation "ERROR" "Échec du changement de mot de passe [$operation_id] pour l'utilisateur : $username"
        log_security_event "PASSWORD_CHANGE_FAILED" "$username" "Échec de l'opération de changement de mot de passe"
        
        # Enregistrer les détails de l'erreur
        if [[ -f "$temp_log" ]]; then
            local error_msg=$(cat "$temp_log")
            log_operation "ERROR" "Erreur dscl : $error_msg"
        fi
        
        # Nettoyer les fichiers temporaires de manière sécurisée
        shred -vfz -n 3 "$temp_log" 2>/dev/null || {
            rm -f "$temp_log"
        }
        
        return 1
    fi
}

# Générer un rapport de gestion des mots de passe
generate_password_report() {
    local report_file="/tmp/macfleet_password_report_$(date +%Y%m%d_%H%M%S).txt"
    
    {
        echo "Rapport de Gestion des Mots de Passe MacFleet"
        echo "Généré : $(date)"
        echo "Nom d'hôte : $(hostname)"
        echo "Administrateur : $(whoami)"
        echo "=================================="
        echo ""
        
        echo "Opérations de Mot de Passe Récentes (Dernières 24 heures) :"
        if [[ -f "$LOG_FILE" ]]; then
            local yesterday=$(date -v-1d '+%Y-%m-%d')
            grep "$yesterday\|$(date '+%Y-%m-%d')" "$LOG_FILE" | grep -E "(PASSWORD_CHANGED|PASSWORD_CHANGE_FAILED)" | tail -50
        else
            echo "Aucun fichier de log trouvé"
        fi
        
        echo ""
        echo "Événements de Sécurité (Dernières 24 heures) :"
        if [[ -f "$AUDIT_LOG" ]]; then
            local yesterday=$(date -v-1d '+%Y-%m-%d')
            grep "$yesterday\|$(date '+%Y-%m-%d')" "$AUDIT_LOG" | tail -20
        else
            echo "Aucun log d'audit trouvé"
        fi
        
        echo ""
        echo "État des Politiques de Mot de Passe :"
        echo "Longueur Minimale : $MIN_PASSWORD_LENGTH"
        echo "Longueur Maximale : $MAX_PASSWORD_LENGTH"
        echo "Complexité Requise : $COMPLEXITY_REQUIREMENTS"
        echo "Nombre d'Historique : $PASSWORD_HISTORY_COUNT"
        echo "Durée de Verrouillage : $LOCKOUT_DURATION secondes"
        
        echo ""
        echo "Résumé des Comptes Utilisateur :"
        local total_users=$(dscl . -list /Users | grep -v '^_' | grep -v '^daemon\|^nobody\|^root' | wc -l)
        echo "Total Utilisateurs Actifs : $total_users"
        
        echo ""
        echo "Informations Système :"
        echo "Version macOS : $(sw_vers -productVersion)"
        echo "Framework de Sécurité : $(security --version 2>/dev/null || echo "Inconnu")"
        
    } > "$report_file"
    
    echo "Rapport de gestion des mots de passe sauvegardé à : $report_file"
    log_operation "INFO" "Rapport de mot de passe généré : $report_file"
}

# Fonction principale de gestion des mots de passe
main() {
    local action="${1:-help}"
    
    case "$action" in
        "change")
            local username="$2"
            local current_password="$3"
            local new_password="$4"
            local force_change="${5:-false}"
            
            if [[ -z "$username" ]]; then
                echo "Usage : $0 change <nom_utilisateur> [mot_de_passe_actuel] [nouveau_mot_de_passe] [forcer]"
                echo "Note : Si les mots de passe ne sont pas fournis, vous serez invité de manière sécurisée"
                exit 1
            fi
            
            # Demander les mots de passe s'ils ne sont pas fournis
            if [[ -z "$current_password" && "$force_change" != "true" ]]; then
                echo -n "Entrez le mot de passe actuel pour $username : "
                read -s current_password
                echo
            fi
            
            if [[ -z "$new_password" ]]; then
                echo -n "Entrez le nouveau mot de passe pour $username (ou appuyez sur Entrée pour générer) : "
                read -s new_password
                echo
                
                if [[ -z "$new_password" ]]; then
                    new_password=$(generate_secure_password)
                    if [[ $? -eq 0 ]]; then
                        echo "Mot de passe sécurisé généré pour $username"
                        echo "Nouveau mot de passe : $new_password"
                        echo "ATTENTION : Sauvegardez ce mot de passe de manière sécurisée et fournissez-le à l'utilisateur"
                    else
                        echo "Échec de génération d'un mot de passe sécurisé"
                        exit 1
                    fi
                fi
            fi
            
            enterprise_change_password "$username" "$current_password" "$new_password" "$force_change"
            ;;
        "generate")
            local length="${2:-16}"
            generate_secure_password "$length"
            ;;
        "validate")
            local password="$2"
            if [[ -z "$password" ]]; then
                echo -n "Entrez le mot de passe à valider : "
                read -s password
                echo
            fi
            
            if validate_password_complexity "$password"; then
                echo "Le mot de passe répond aux exigences de complexité"
                exit 0
            else
                echo "Le mot de passe ne répond pas aux exigences de complexité"
                exit 1
            fi
            ;;
        "report")
            generate_password_report
            ;;
        "help"|*)
            echo "$SCRIPT_NAME v$VERSION"
            echo "Gestion Entreprise de Changement de Mot de Passe"
            echo ""
            echo "Usage : $0 <action> [options]"
            echo ""
            echo "Actions :"
            echo "  change <nom_utilisateur> [mot_actuel] [nouveau_mot] [forcer]     - Changer le mot de passe utilisateur"
            echo "  generate [longueur]                                               - Générer un mot de passe sécurisé"
            echo "  validate [mot_de_passe]                                          - Valider la complexité du mot de passe"
            echo "  report                                                            - Générer un rapport de gestion des mots de passe"
            echo "  help                                                              - Afficher ce message d'aide"
            echo ""
            echo "Fonctionnalités :"
            echo "  • Validation de complexité de mot de passe de niveau entreprise"
            echo "  • Journalisation d'audit de sécurité complète"
            echo "  • Suivi d'historique et prévention de réutilisation des mots de passe"
            echo "  • Génération de mots de passe aléatoires sécurisés"
            echo "  • Synchronisation du trousseau"
            echo "  • Application des heures de bureau et des permissions"
            echo "  • Protection des comptes système"
            echo ""
            echo "Fonctionnalités de Sécurité :"
            echo "  • Vérification d'authentification multi-couches"
            echo "  • Gestion sécurisée des identifiants avec nettoyage de mémoire"
            echo "  • Piste d'audit complète pour la conformité"
            echo "  • Surveillance des événements de sécurité en temps réel"
            echo "  • Notifications de sécurité automatisées"
            ;;
    esac
}

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

Commandes de Référence Rapide

Changements de Mot de Passe Uniques

# Changement de mot de passe interactif
./password_manager.sh change jean.dupont

# Changement de mot de passe avec mot de passe actuel
./password_manager.sh change jean.dupont "mot_de_passe_actuel" "nouveau_mot_de_passe_securise"

# Changement de mot de passe forcé (admin uniquement)
./password_manager.sh change jean.dupont "" "nouveau_mot_de_passe" true

Génération et Validation de Mots de Passe

# Générer un mot de passe sécurisé (16 caractères par défaut)
./password_manager.sh generate

# Générer un mot de passe avec longueur spécifique
./password_manager.sh generate 20

# Valider la complexité du mot de passe
./password_manager.sh validate "MonMotDePasse123!"

# Validation interactive de mot de passe
./password_manager.sh validate

Exemples d'Intégration

Intégration JAMF Pro

#!/bin/bash

# Script JAMF Pro pour gestion de mots de passe entreprise
# Paramètres : $4 = action, $5 = nom_utilisateur, $6 = nouveau_mot_de_passe, $7 = changement_force

ACTION="$4"
NOM_UTILISATEUR="$5"
NOUVEAU_MOT_DE_PASSE="$6"
CHANGEMENT_FORCE="${7:-false}"

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

# Exécuter l'opération de mot de passe
case "$ACTION" in
    "change")
        if [[ -z "$NOUVEAU_MOT_DE_PASSE" ]]; then
            # Générer un mot de passe sécurisé
            NOUVEAU_MOT_DE_PASSE=$(/usr/local/bin/macfleet_password_manager.sh generate 16)
        fi
        
        /usr/local/bin/macfleet_password_manager.sh change "$NOM_UTILISATEUR" "" "$NOUVEAU_MOT_DE_PASSE" "$CHANGEMENT_FORCE"
        
        echo "Mot de passe changé pour $NOM_UTILISATEUR"
        ;;
    *)
        echo "Action invalide : $ACTION"
        exit 1
        ;;
esac

# Générer un rapport
/usr/local/bin/macfleet_password_manager.sh report

exit $?

Fonctionnalités de Sécurité

Gestion Sécurisée des Mots de Passe

# Nettoyage sécurisé de la mémoire
cleanup_sensitive_data() {
    local password_var="$1"
    
    # Effacer le contenu de la variable
    unset "$password_var"
    
    # Effacer l'historique bash des commandes sensibles
    history -c
    history -w
    
    # Effacer les fichiers temporaires
    find "$TEMP_DIR" -name "*.tmp" -type f -exec shred -vfz -n 3 {} \; 2>/dev/null
}

# Saisie sécurisée de mot de passe
secure_password_input() {
    local prompt="$1"
    local password=""
    
    echo -n "$prompt"
    
    # Désactiver l'écho et lire le mot de passe
    stty -echo
    read password
    stty echo
    echo
    
    echo "$password"
}

Dépannage

Problèmes Courants et Solutions

ProblèmeCauseSolution
Permission refuséePrivilèges insuffisantsExécuter en tant qu'admin ou root
Mot de passe actuel incorrectMauvais mot de passe actuelVérifier le mot de passe actuel ou utiliser le changement forcé
Échec de complexité du mot de passeMot de passe faibleUtiliser le générateur de mot de passe ou renforcer le mot de passe
Échec de mise à jour du trousseauTrousseau verrouillé ou corrompuDéverrouiller manuellement le trousseau ou le réinitialiser
Protection du compte systèmeTentative de changement sur un utilisateur systèmeUtiliser uniquement des comptes utilisateur réguliers

Analyse des Logs

# Voir les opérations de mot de passe récentes
tail -f /var/log/macfleet_password_operations.log

# Rechercher les événements de sécurité
grep "SECURITY_EVENT" /var/log/macfleet_password_audit.log

# Compter les changements de mot de passe par utilisateur
grep "PASSWORD_CHANGED" /var/log/macfleet_password_audit.log | cut -d'|' -f4 | sort | uniq -c

Meilleures Pratiques

  1. Utiliser des politiques de mot de passe robustes avec des exigences de complexité
  2. Activer l'historique des mots de passe pour prévenir la réutilisation
  3. Implémenter une rotation régulière des mots de passe pour les comptes à privilèges élevés
  4. Surveiller les logs d'audit pour les activités suspectes
  5. Utiliser la génération de mots de passe sécurisés pour les mots de passe temporaires
  6. Intégrer avec les services d'annuaire pour une gestion centralisée
  7. Tester les changements de mot de passe sur des systèmes non-productifs d'abord
  8. Implémenter des procédures d'urgence pour les verrouillages de compte

Ce système de gestion de changement de mot de passe entreprise fournit des contrôles de sécurité complets, des capacités d'audit et l'application de politiques tout en maintenant la fiabilité de la commande dscl de base pour une gestion efficace des mots de passe de flotte.

Gestion de Paquets d'Entreprise avec Homebrew sur macOS

Rationalisez le déploiement logiciel et la gestion de paquets sur vos appareils MacFleet en utilisant Homebrew. Ce tutoriel couvre l'installation de logiciels d'entreprise, la gestion de configuration, le suivi de conformité et les flux de déploiement automatisés pour une gestion complète de flotte.

Comprendre Homebrew pour l'Entreprise

Homebrew fournit une gestion de paquets puissante pour macOS :

  • Paquets Formula - Outils en ligne de commande et bibliothèques
  • Applications Cask - Applications GUI et gros binaires
  • Dépôts Tap - Sources de paquets tiers
  • Fichiers Bundle - Manifestes de paquets déclaratifs
  • Services - Gestion de démons en arrière-plan

Installation Homebrew Basique

Installer Homebrew

#!/bin/bash

# Installer le gestionnaire de paquets Homebrew
install_homebrew() {
    echo "=== Installation du Gestionnaire de Paquets Homebrew ==="
    
    # Vérifier si Homebrew est déjà installé
    if command -v brew >/dev/null 2>&1; then
        echo "✅ Homebrew déjà installé : $(brew --version | head -1)"
        return 0
    fi
    
    echo "📦 Installation de Homebrew..."
    
    # Installer Homebrew
    if /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"; then
        echo "✅ Installation de Homebrew terminée"
        
        # Ajouter Homebrew au PATH pour la session actuelle
        if [[ -f "/opt/homebrew/bin/brew" ]]; then
            eval "$(/opt/homebrew/bin/brew shellenv)"
        elif [[ -f "/usr/local/bin/brew" ]]; then
            eval "$(/usr/local/bin/brew shellenv)"
        fi
        
        # Vérifier l'installation
        if command -v brew >/dev/null 2>&1; then
            echo "🔍 Version Homebrew : $(brew --version | head -1)"
            return 0
        else
            echo "❌ Échec de la vérification d'installation Homebrew"
            return 1
        fi
    else
        echo "❌ Échec de l'installation Homebrew"
        return 1
    fi
}

# Exécuter l'installation
install_homebrew

Script d'Installation de Paquets Amélioré

#!/bin/bash

# Installation de paquets améliorée basée sur GitHub Gist
# Référence : https://gist.github.com/CliffordAnderson/817777b5dc0e67769e4b

enhanced_package_installation() {
    echo "=== Installation de Paquets Améliorée ==="
    
    # S'assurer que Homebrew est installé
    if ! command -v brew >/dev/null 2>&1; then
        echo "❌ Homebrew non trouvé. Installation..."
        install_homebrew || return 1
    fi
    
    # Mettre à jour Homebrew
    echo "🔄 Mise à jour de Homebrew..."
    brew update
    
    # Langages de programmation
    echo "💻 Installation des langages de programmation..."
    brew install scala
    brew install --cask r
    brew install openjdk
    
    # Outils de développement
    echo "🛠️ Installation des outils de développement..."
    brew install docker
    brew install git
    brew install --cask github
    brew install --cask visual-studio-code
    brew install --cask hyper
    
    # Applications de communication
    echo "💬 Installation des applications de communication..."
    brew install --cask discord
    brew install --cask microsoft-teams
    brew install --cask slack
    brew install --cask zoom
    
    # Outils web
    echo "🌐 Installation des outils web..."
    brew install httpie
    brew install node
    brew install nvm
    brew install --cask firefox
    brew install --cask google-chrome
    brew install --cask postman
    
    # Stockage de fichiers
    echo "📁 Installation des outils de stockage de fichiers..."
    brew install --cask dropbox
    brew install --cask onedrive
    
    # Applications d'écriture
    echo "✍️ Installation des applications d'écriture..."
    brew install pandoc
    brew install --cask zotero
    brew install --cask microsoft-word
    
    # Autres applications
    echo "🎯 Installation d'applications supplémentaires..."
    brew install --cask anki
    
    echo "✅ Installation de paquets terminée"
}

# Exécuter l'installation améliorée
enhanced_package_installation

Système de Gestion Homebrew d'Entreprise

#!/bin/bash

# Système de Gestion Homebrew d'Entreprise MacFleet
# Déploiement de paquets complet, suivi de conformité et gestion de flotte

# Configuration
LOG_FILE="/var/log/macfleet_homebrew.log"
CONFIG_DIR="/etc/macfleet/packages"
PROFILES_DIR="$CONFIG_DIR/profiles"
CACHE_DIR="/var/cache/macfleet/homebrew"
REPORTS_DIR="$CONFIG_DIR/reports"
COMPLIANCE_DIR="$CONFIG_DIR/compliance"

# Profils de paquets pour différents rôles
declare -A PACKAGE_PROFILES=(
    ["developpeur"]="git,node,python,docker,visual-studio-code,github,postman,hyper"
    ["designer"]="adobe-creative-cloud,figma,sketch,canva,affinity-designer,imageoptim"
    ["manager"]="microsoft-office,slack,zoom,teams,dropbox,onedrive,notion"
    ["analyste"]="r,python,tableau,microsoft-excel,jupyter-notebook,pandas"
    ["securite"]="wireshark,nmap,burp-suite,malwarebytes,1password,gpg-suite"
    ["education"]="zoom,microsoft-office,rstudio,zotero,anki,mendeley"
    ["minimal"]="google-chrome,firefox,zoom,slack"
    ["entreprise"]="microsoft-office,teams,onedrive,1password,chrome-enterprise"
)

# Cadres de conformité
declare -A COMPLIANCE_PACKAGES=(
    ["hipaa"]="1password,malwarebytes,gpg-suite,microsoft-office"
    ["sox"]="microsoft-office,1password,box-drive,tableau"
    ["rgpd"]="1password,gpg-suite,notion,signal"
    ["iso27001"]="1password,malwarebytes,gpg-suite,microsoft-defender"
)

# Suivi des licences
declare -A LICENSE_REQUIRED=(
    ["microsoft-office"]="commercial"
    ["adobe-creative-cloud"]="commercial"
    ["tableau"]="commercial"
    ["sketch"]="commercial"
    ["1password"]="commercial"
    ["zoom"]="freemium"
    ["slack"]="freemium"
    ["notion"]="freemium"
)

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

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

# S'assurer que Homebrew est installé et configuré
ensure_homebrew() {
    log_action "S'assurer que Homebrew est correctement configuré"
    
    # Vérifier si Homebrew est installé
    if ! command -v brew >/dev/null 2>&1; then
        log_action "Installation de Homebrew..."
        if ! /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"; then
            log_action "❌ Échec de l'installation Homebrew"
            return 1
        fi
        
        # Configurer PATH
        if [[ -f "/opt/homebrew/bin/brew" ]]; then
            eval "$(/opt/homebrew/bin/brew shellenv)"
        elif [[ -f "/usr/local/bin/brew" ]]; then
            eval "$(/usr/local/bin/brew shellenv)"
        fi
    fi
    
    # Mettre à jour Homebrew
    log_action "Mise à jour de Homebrew..."
    brew update 2>/dev/null || log_action "⚠️ Échec de la mise à jour Homebrew"
    
    # Vérifier la santé de Homebrew
    if brew doctor >/dev/null 2>&1; then
        log_action "✅ Vérification de santé Homebrew réussie"
    else
        log_action "⚠️ Problèmes détectés lors de la vérification de santé Homebrew"
    fi
    
    return 0
}

# Installer des paquets depuis un profil
install_package_profile() {
    local profile_name="$1"
    local dry_run="${2:-false}"
    
    log_action "Installation du profil de paquets : $profile_name (dry_run: $dry_run)"
    
    # Obtenir les paquets du profil
    local profile_packages="${PACKAGE_PROFILES[$profile_name]}"
    if [[ -z "$profile_packages" ]]; then
        log_action "❌ Profil inconnu : $profile_name"
        return 1
    fi
    
    # S'assurer que Homebrew est prêt
    ensure_homebrew || return 1
    
    # Analyser les paquets
    IFS=',' read -ra PACKAGES <<< "$profile_packages"
    
    local success_count=0
    local failure_count=0
    local already_installed=0
    
    for package in "${PACKAGES[@]}"; do
        # Nettoyer le nom du paquet
        package=$(echo "$package" | sed 's/^[ \t]*//;s/[ \t]*$//')
        
        log_action "Traitement du paquet : $package"
        
        if [[ "$dry_run" == "true" ]]; then
            echo "Installerait : $package"
            continue
        fi
        
        # Vérifier si déjà installé
        if is_package_installed "$package"; then
            log_action "✅ Paquet déjà installé : $package"
            already_installed=$((already_installed + 1))
            continue
        fi
        
        # Installer le paquet
        if install_single_package "$package"; then
            log_action "✅ Installation réussie : $package"
            success_count=$((success_count + 1))
        else
            log_action "❌ Échec de l'installation : $package"
            failure_count=$((failure_count + 1))
        fi
    done
    
    # Résumé
    log_action "Résumé d'installation - Succès : $success_count, Échecs : $failure_count, Déjà installés : $already_installed"
    
    # Générer un rapport d'installation
    generate_installation_report "$profile_name" "$success_count" "$failure_count" "$already_installed"
    
    return 0
}

# Vérifier si un paquet est installé
is_package_installed() {
    local package="$1"
    
    # Vérifier si c'est un cask
    if brew list --cask "$package" >/dev/null 2>&1; then
        return 0
    fi
    
    # Vérifier si c'est une formula
    if brew list "$package" >/dev/null 2>&1; then
        return 0
    fi
    
    return 1
}

# Installer un seul paquet
install_single_package() {
    local package="$1"
    
    # Essayer d'abord comme cask (pour les applications GUI)
    if brew install --cask "$package" 2>/dev/null; then
        return 0
    fi
    
    # Essayer comme formula (pour les outils CLI)
    if brew install "$package" 2>/dev/null; then
        return 0
    fi
    
    return 1
}

# Générer un inventaire logiciel complet
generate_software_inventory() {
    log_action "Génération de l'inventaire logiciel complet"
    
    local inventory_file="$REPORTS_DIR/software_inventory_$(date '+%Y%m%d_%H%M%S').json"
    
    cat > "$inventory_file" << EOF
{
    "inventory_metadata": {
        "timestamp": "$(date -Iseconds)",
        "hostname": "$(hostname)",
        "os_version": "$(sw_vers -productVersion)",
        "homebrew_version": "$(brew --version | head -1)",
        "generator": "MacFleet Homebrew Manager"
    },
    "installed_packages": {
        "formulae": $(brew list --formula --json),
        "casks": $(brew list --cask --json)
    },
    "package_summary": {
        "total_formulae": $(brew list --formula | wc -l | tr -d ' '),
        "total_casks": $(brew list --cask | wc -l | tr -d ' '),
        "outdated_packages": $(brew outdated --json)
    },
    "system_info": {
        "homebrew_prefix": "$(brew --prefix)",
        "homebrew_cellar": "$(brew --cellar)",
        "homebrew_cache": "$(brew --cache)"
    }
}
EOF

    log_action "✅ Inventaire logiciel généré : $inventory_file"
    echo "$inventory_file"
}

# Vérification de conformité des licences
check_license_compliance() {
    log_action "Vérification de conformité des licences pour les paquets installés"
    
    local compliance_report="$COMPLIANCE_DIR/license_compliance_$(date '+%Y%m%d_%H%M%S').json"
    
    cat > "$compliance_report" << EOF
{
    "compliance_metadata": {
        "timestamp": "$(date -Iseconds)",
        "hostname": "$(hostname)",
        "check_type": "license_compliance"
    },
    "license_analysis": [
EOF

    local first=true
    local compliance_issues=0
    
    # Vérifier les casks installés pour les exigences de licence
    while IFS= read -r package; do
        local license_type="${LICENSE_REQUIRED[$package]}"
        
        if [[ -n "$license_type" ]]; then
            if [[ "$first" == true ]]; then
                first=false
            else
                echo "," >> "$compliance_report"
            fi
            
            local compliance_status="unknown"
            local needs_attention=false
            
            case "$license_type" in
                "commercial")
                    compliance_status="requires_license"
                    needs_attention=true
                    compliance_issues=$((compliance_issues + 1))
                    ;;
                "freemium")
                    compliance_status="freemium_check_usage"
                    ;;
            esac
            
            cat >> "$compliance_report" << EOF
        {
            "package": "$package",
            "license_type": "$license_type",
            "compliance_status": "$compliance_status",
            "needs_attention": $needs_attention,
            "installed_date": "$(brew list --cask --versions "$package" 2>/dev/null | awk '{print $2}' || echo 'unknown')"
        }
EOF
        fi
    done < <(brew list --cask)
    
    cat >> "$compliance_report" << EOF
    ],
    "summary": {
        "total_packages_checked": $(brew list --cask | wc -l | tr -d ' '),
        "license_issues_found": $compliance_issues,
        "compliance_status": "$([ $compliance_issues -eq 0 ] && echo 'compliant' || echo 'requires_attention')"
    }
}
EOF

    log_action "✅ Vérification de conformité des licences terminée : $compliance_report"
    echo "$compliance_report"
}

# Mettre à jour tous les paquets
update_all_packages() {
    local update_mode="${1:-safe}"  # safe, aggressive, ou security-only
    
    log_action "Démarrage des mises à jour de paquets (mode : $update_mode)"
    
    # S'assurer que Homebrew est prêt
    ensure_homebrew || return 1
    
    # Mettre à jour Homebrew lui-même
    log_action "Mise à jour de Homebrew..."
    if brew update; then
        log_action "✅ Homebrew mis à jour avec succès"
    else
        log_action "❌ Échec de la mise à jour Homebrew"
        return 1
    fi
    
    # Obtenir les paquets obsolètes
    local outdated_formulae outdated_casks
    outdated_formulae=$(brew outdated --formula --quiet)
    outdated_casks=$(brew outdated --cask --quiet)
    
    case "$update_mode" in
        "safe")
            # Mettre à jour uniquement les formulae (les outils CLI sont généralement plus sûrs à mettre à jour)
            if [[ -n "$outdated_formulae" ]]; then
                log_action "Mise à jour des formulae obsolètes : $outdated_formulae"
                brew upgrade
            fi
            ;;
        "aggressive")
            # Tout mettre à jour
            if [[ -n "$outdated_formulae" ]]; then
                log_action "Mise à jour de toutes les formulae obsolètes"
                brew upgrade
            fi
            if [[ -n "$outdated_casks" ]]; then
                log_action "Mise à jour de tous les casks obsolètes"
                brew upgrade --cask
            fi
            ;;
        "security-only")
            # Mettre à jour uniquement les paquets avec des problèmes de sécurité connus
            # Cela nécessiterait une intégration avec des bases de données de vulnérabilités
            log_action "Mises à jour de sécurité uniquement pas encore implémentées"
            ;;
    esac
    
    # Nettoyage
    log_action "Nettoyage des anciennes versions..."
    brew cleanup
    
    log_action "✅ Mises à jour de paquets terminées"
    
    # Générer un inventaire post-mise à jour
    generate_software_inventory
}

# Générer un Brewfile pour l'installation actuelle
generate_brewfile() {
    local brewfile_path="${1:-$CONFIG_DIR/Brewfile}"
    
    log_action "Génération du Brewfile : $brewfile_path"
    
    # Créer l'en-tête du Brewfile
    cat > "$brewfile_path" << EOF
# MacFleet Brewfile
# Généré le $(date)
# Nom d'hôte : $(hostname)

# Taps
EOF

    # Ajouter les taps
    brew tap | while read -r tap; do
        echo "tap \"$tap\"" >> "$brewfile_path"
    done
    
    echo "" >> "$brewfile_path"
    echo "# Formulae" >> "$brewfile_path"
    
    # Ajouter les formulae
    brew list --formula | while read -r formula; do
        echo "brew \"$formula\"" >> "$brewfile_path"
    done
    
    echo "" >> "$brewfile_path"
    echo "# Casks" >> "$brewfile_path"
    
    # Ajouter les casks
    brew list --cask | while read -r cask; do
        echo "cask \"$cask\"" >> "$brewfile_path"
    done
    
    log_action "✅ Brewfile généré : $brewfile_path"
    echo "$brewfile_path"
}

# Installer depuis un Brewfile
install_from_brewfile() {
    local brewfile_path="$1"
    local dry_run="${2:-false}"
    
    if [[ ! -f "$brewfile_path" ]]; then
        log_action "❌ Brewfile non trouvé : $brewfile_path"
        return 1
    fi
    
    log_action "Installation depuis le Brewfile : $brewfile_path (dry_run: $dry_run)"
    
    # S'assurer que Homebrew est prêt
    ensure_homebrew || return 1
    
    if [[ "$dry_run" == "true" ]]; then
        log_action "Exécution à sec - installerait les paquets depuis : $brewfile_path"
        brew bundle --file="$brewfile_path" --verbose --no-install
    else
        # Installer les paquets depuis le Brewfile
        if brew bundle --file="$brewfile_path"; then
            log_action "✅ Installation Brewfile terminée"
            return 0
        else
            log_action "❌ Échec de l'installation Brewfile"
            return 1
        fi
    fi
}

# Audit de sécurité des paquets installés
security_audit() {
    log_action "Exécution de l'audit de sécurité des paquets installés"
    
    local audit_report="$REPORTS_DIR/security_audit_$(date '+%Y%m%d_%H%M%S').json"
    
    cat > "$audit_report" << EOF
{
    "audit_metadata": {
        "timestamp": "$(date -Iseconds)",
        "hostname": "$(hostname)",
        "audit_type": "security"
    },
    "security_findings": [
EOF

    local first=true
    local security_issues=0
    
    # Vérifier les paquets vulnérables connus (vérification simplifiée)
    # En production, cela s'intégrerait avec des bases de données CVE
    local vulnerable_packages=("python@3.8" "node@14" "openssl@1.1")
    
    for vuln_package in "${vulnerable_packages[@]}"; do
        if is_package_installed "$vuln_package"; then
            if [[ "$first" == true ]]; then
                first=false
            else
                echo "," >> "$audit_report"
            fi
            
            cat >> "$audit_report" << EOF
        {
            "package": "$vuln_package",
            "severity": "medium",
            "issue": "potentially_outdated_version",
            "recommendation": "update_to_latest_version",
            "installed_version": "$(brew list --versions "$vuln_package" | awk '{print $2}')"
        }
EOF
            security_issues=$((security_issues + 1))
        fi
    done
    
    cat >> "$audit_report" << EOF
    ],
    "summary": {
        "total_packages_audited": $(( $(brew list --formula | wc -l) + $(brew list --cask | wc -l) )),
        "security_issues_found": $security_issues,
        "security_status": "$([ $security_issues -eq 0 ] && echo 'secure' || echo 'requires_attention')"
    }
}
EOF

    log_action "✅ Audit de sécurité terminé : $audit_report"
    echo "$audit_report"
}

# Générer un rapport d'installation
generate_installation_report() {
    local profile_name="$1"
    local success_count="$2"
    local failure_count="$3"
    local already_installed="$4"
    
    local report_file="$REPORTS_DIR/installation_report_${profile_name}_$(date '+%Y%m%d_%H%M%S').json"
    
    cat > "$report_file" << EOF
{
    "installation_metadata": {
        "timestamp": "$(date -Iseconds)",
        "hostname": "$(hostname)",
        "profile": "$profile_name",
        "generator": "MacFleet Homebrew Manager"
    },
    "installation_results": {
        "successful_installations": $success_count,
        "failed_installations": $failure_count,
        "already_installed": $already_installed,
        "total_processed": $(( success_count + failure_count + already_installed ))
    },
    "post_installation_inventory": $(generate_software_inventory | tail -n +2 | head -n -1)
}
EOF

    log_action "✅ Rapport d'installation généré : $report_file"
    echo "$report_file"
}

# Fonction d'exécution principale
main() {
    local action="${1:-inventory}"
    local parameter="$2"
    local additional_param="$3"
    
    log_action "=== Démarrage de la Gestion Homebrew MacFleet ==="
    log_action "Action : $action"
    log_action "Paramètre : ${parameter:-N/A}"
    
    setup_directories
    
    case "$action" in
        "install-profile")
            if [[ -z "$parameter" ]]; then
                echo "Profils de paquets disponibles :"
                for profile in "${!PACKAGE_PROFILES[@]}"; do
                    echo "  - $profile : ${PACKAGE_PROFILES[$profile]}"
                done
                echo ""
                echo "Usage : $0 install-profile <nom_profil> [dry_run]"
                exit 1
            fi
            install_package_profile "$parameter" "$additional_param"
            ;;
        "inventory")
            generate_software_inventory
            ;;
        "update")
            update_all_packages "$parameter"
            ;;
        "compliance")
            check_license_compliance
            ;;
        "security")
            security_audit
            ;;
        "brewfile-generate")
            generate_brewfile "$parameter"
            ;;
        "brewfile-install")
            if [[ -z "$parameter" ]]; then
                echo "Usage : $0 brewfile-install <chemin_brewfile> [dry_run]"
                exit 1
            fi
            install_from_brewfile "$parameter" "$additional_param"
            ;;
        "ensure")
            ensure_homebrew
            ;;
        *)
            echo "Usage : $0 {install-profile|inventory|update|compliance|security|brewfile-generate|brewfile-install|ensure}"
            echo "  install-profile    - Installer les paquets depuis un profil prédéfini"
            echo "  inventory         - Générer un rapport d'inventaire logiciel"
            echo "  update           - Mettre à jour tous les paquets (safe|aggressive|security-only)"
            echo "  compliance       - Vérifier la conformité des licences"
            echo "  security         - Effectuer un audit de sécurité"
            echo "  brewfile-generate - Générer un Brewfile depuis l'installation actuelle"
            echo "  brewfile-install  - Installer les paquets depuis un Brewfile"
            echo "  ensure           - S'assurer que Homebrew est installé et configuré"
            exit 1
            ;;
    esac
    
    log_action "=== Gestion Homebrew terminée ==="
}

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

Fonctionnalités Avancées de Gestion de Paquets

Création de Profil de Paquet Personnalisé

#!/bin/bash

# Créer un profil de paquet personnalisé
create_custom_profile() {
    local profile_name="$1"
    local packages="$2"
    
    echo "=== Création d'un Profil de Paquet Personnalisé ==="
    echo "Profil : $profile_name"
    echo "Paquets : $packages"
    
    # Valider que les paquets existent
    IFS=',' read -ra PACKAGE_LIST <<< "$packages"
    local valid_packages=()
    
    for package in "${PACKAGE_LIST[@]}"; do
        package=$(echo "$package" | sed 's/^[ \t]*//;s/[ \t]*$//')
        
        # Vérifier si le paquet existe dans Homebrew
        if brew search --formula --cask "$package" | grep -q "^$package$"; then
            valid_packages+=("$package")
            echo "✅ Paquet valide : $package"
        else
            echo "⚠️  Paquet non trouvé : $package"
        fi
    done
    
    if [[ ${#valid_packages[@]} -eq 0 ]]; then
        echo "❌ Aucun paquet valide trouvé"
        return 1
    fi
    
    # Créer le profil
    local profile_packages
    printf -v profile_packages '%s,' "${valid_packages[@]}"
    profile_packages=${profile_packages%,}  # Supprimer la virgule finale
    
    PACKAGE_PROFILES["$profile_name"]="$profile_packages"
    
    echo "✅ Profil personnalisé créé : $profile_name"
    echo "Paquets : $profile_packages"
}

Gestion Automatisée des Licences

#!/bin/bash

# Gestion et suivi automatisés des licences
manage_software_licenses() {
    echo "=== Gestion des Licences Logicielles ==="
    
    local license_db="$COMPLIANCE_DIR/license_database.json"
    
    # Créer la base de données de licences si elle n'existe pas
    if [[ ! -f "$license_db" ]]; then
        cat > "$license_db" << EOF
{
    "license_metadata": {
        "created": "$(date -Iseconds)",
        "last_updated": "$(date -Iseconds)"
    },
    "licenses": {},
    "compliance_rules": {}
}
EOF
    fi
    
    # Scanner les logiciels commerciaux
    local commercial_software=()
    while IFS= read -r package; do
        if [[ -n "${LICENSE_REQUIRED[$package]}" ]]; then
            commercial_software+=("$package")
        fi
    done < <(brew list --cask)
    
    echo "Trouvé ${#commercial_software[@]} paquets nécessitant une gestion de licence :"
    printf '%s\n' "${commercial_software[@]}"
    
    # Générer un rapport de licences
    local license_report="$REPORTS_DIR/license_report_$(date '+%Y%m%d_%H%M%S').json"
    
    cat > "$license_report" << EOF
{
    "license_report_metadata": {
        "timestamp": "$(date -Iseconds)",
        "hostname": "$(hostname)"
    },
    "commercial_software": [
EOF

    local first=true
    for package in "${commercial_software[@]}"; do
        if [[ "$first" == true ]]; then
            first=false
        else
            echo "," >> "$license_report"
        fi
        
        cat >> "$license_report" << EOF
        {
            "package": "$package",
            "license_type": "${LICENSE_REQUIRED[$package]}",
            "installed_version": "$(brew list --cask --versions "$package" 2>/dev/null | awk '{print $2}' || echo 'unknown')",
            "license_status": "requires_verification"
        }
EOF
    done
    
    cat >> "$license_report" << EOF
    ]
}
EOF

    echo "📋 Rapport de licences généré : $license_report"
}

Meilleures Pratiques

🚀 Déploiement d'Entreprise

  • Installations basées sur les profils pour différents rôles utilisateur et départements
  • Gestion centralisée des paquets avec déploiement Brewfile sur les flottes
  • Suivi automatisé de l'inventaire logiciel et rapports
  • Surveillance de conformité des licences avec audit automatisé

🔐 Gestion de Sécurité

  • Audits de sécurité réguliers des paquets installés et dépendances
  • Intégration de scan de vulnérabilités avec bases de données CVE
  • Vérification de signature de paquets et validation de sources fiables
  • Déploiement contrôlé des mises à jour avec phases de test

📋 Conformité et Gouvernance

  • Suivi des licences pour la conformité des logiciels commerciaux
  • Application de politiques basée sur les exigences organisationnelles
  • Pistes d'audit pour toutes les installations et mises à jour de paquets
  • Gestion des coûts grâce à l'optimisation des licences

🔧 Maintenance et Optimisation

  • Mises à jour automatisées avec capacités de retour en arrière
  • Nettoyage et optimisation pour gérer l'espace disque
  • Surveillance des performances des opérations de gestion de paquets
  • Création de profils personnalisés pour des cas d'usage spécialisés

Notes Importantes

  • Tester les déploiements en environnements de staging avant le déploiement en production
  • Sauvegarder les configurations avant les mises à jour majeures de paquets
  • Surveiller la conformité des licences pour éviter les risques légaux et financiers
  • Audits d'inventaire réguliers pour maintenir un suivi logiciel précis
  • Considérations de bande passante réseau pour les déploiements à grande échelle
  • Communication utilisateur pour les changements et mises à jour logiciels

Intégration avec les Systèmes d'Entreprise

Le système de gestion Homebrew peut être intégré avec :

  • Solutions MDM pour l'application de politiques
  • Systèmes de gestion d'actifs pour le suivi d'inventaire
  • Plateformes de gestion de licences pour l'automatisation de conformité
  • Outils de sécurité pour l'évaluation de vulnérabilités
  • Systèmes de surveillance pour le suivi de déploiement

Gestion d'Entreprise des Notifications et Optimisation de l'Expérience Utilisateur sur macOS

Optimisez la productivité des utilisateurs et maintenez les standards de communication d'entreprise sur vos appareils MacFleet avec une gestion complète des notifications et l'optimisation de l'expérience utilisateur. Ce tutoriel couvre les contrôles avancés de notifications, l'amélioration de la productivité, la gestion des distractions et l'application automatisée de politiques pour une efficacité organisationnelle améliorée.

Comprendre la Gestion des Notifications macOS

Le système de notifications macOS remplit plusieurs fonctions d'entreprise :

  • Hub de Communication - Livraison centralisée de messages et alertes utilisateur
  • Contrôleur de Productivité - Gestion des interruptions et temps de concentration
  • Passerelle de Sécurité - Contrôle de l'exposition d'informations et accès
  • Optimiseur d'Expérience Utilisateur - Équilibrage livraison d'informations et efficacité workflow
  • Applicateur de Politiques d'Entreprise - Assurance conformité standards communication

Gestion Basique du Centre de Notifications

Désactiver le Centre de Notifications

#!/bin/bash

# Désactiver le Centre de Notifications pour l'utilisateur actuel
disable_notification_center() {
    echo "=== Désactivation du Centre de Notifications ==="
    
    # Obtenir l'utilisateur actuellement connecté
    local current_user=$(echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ { print $3 }')
    
    # Valider la connexion utilisateur
    if [[ -z "$current_user" || "$current_user" == "loginwindow" ]]; then
        echo "❌ Aucun utilisateur connecté, impossible de continuer"
        return 1
    fi
    
    echo "Désactivation du Centre de Notifications pour l'utilisateur: $current_user"
    
    # Obtenir l'UID utilisateur
    local uid=$(id -u "$current_user")
    
    # Fonction pour exécuter des commandes en tant qu'utilisateur actuel
    run_as_user() {
        if [[ "$current_user" != "loginwindow" ]]; then
            launchctl asuser "$uid" sudo -u "$current_user" "$@"
        else
            echo "❌ Aucune session utilisateur valide"
            return 1
        fi
    }
    
    # Vérifier le statut SIP avant de continuer
    local sip_status=$(csrutil status | grep -o "enabled\|disabled")
    if [[ "$sip_status" == "enabled" ]]; then
        echo "⚠️  System Integrity Protection (SIP) est activé"
        echo "   Gestion alternative des notifications sera appliquée"
        apply_alternative_notification_management "$current_user"
        return 0
    fi
    
    # Désactiver le Centre de Notifications (nécessite SIP désactivé)
    if run_as_user launchctl unload -w /System/Library/LaunchAgents/com.apple.notificationcenterui.plist 2>/dev/null; then
        echo "✅ Centre de Notifications désactivé avec succès"
        
        # Enregistrer l'action
        logger "MacFleet: Centre de Notifications désactivé pour l'utilisateur $current_user"
    else
        echo "⚠️  Désactivation directe échouée, application gestion alternative"
        apply_alternative_notification_management "$current_user"
    fi
    
    return 0
}

# Exécuter la fonction
disable_notification_center

Activer le Centre de Notifications

#!/bin/bash

# Activer le Centre de Notifications pour l'utilisateur actuel
enable_notification_center() {
    echo "=== Activation du Centre de Notifications ==="
    
    # Obtenir l'utilisateur actuellement connecté
    local current_user=$(echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ { print $3 }')
    
    # Valider la connexion utilisateur
    if [[ -z "$current_user" || "$current_user" == "loginwindow" ]]; then
        echo "❌ Aucun utilisateur connecté, impossible de continuer"
        return 1
    fi
    
    echo "Activation du Centre de Notifications pour l'utilisateur: $current_user"
    
    # Obtenir l'UID utilisateur
    local uid=$(id -u "$current_user")
    
    # Fonction pour exécuter des commandes en tant qu'utilisateur actuel
    run_as_user() {
        if [[ "$current_user" != "loginwindow" ]]; then
            launchctl asuser "$uid" sudo -u "$current_user" "$@"
        else
            echo "❌ Aucune session utilisateur valide"
            return 1
        fi
    }
    
    # Vérifier le statut SIP
    local sip_status=$(csrutil status | grep -o "enabled\|disabled")
    if [[ "$sip_status" == "enabled" ]]; then
        echo "✅ System Integrity Protection (SIP) est activé (recommandé)"
        echo "   Application gestion notifications compatible SIP"
        configure_sip_compatible_notifications "$current_user"
        return 0
    fi
    
    # Activer le Centre de Notifications (nécessite SIP désactivé)
    if run_as_user launchctl load -w /System/Library/LaunchAgents/com.apple.notificationcenterui.plist 2>/dev/null; then
        echo "✅ Centre de Notifications activé avec succès"
        
        # Enregistrer l'action
        logger "MacFleet: Centre de Notifications activé pour l'utilisateur $current_user"
    else
        echo "⚠️  Activation directe échouée, application configuration alternative"
        configure_sip_compatible_notifications "$current_user"
    fi
    
    return 0
}

# Exécuter la fonction
enable_notification_center

Gestion Alternative Compatible SIP

#!/bin/bash

# Appliquer la gestion des notifications sans nécessiter la désactivation SIP
apply_alternative_notification_management() {
    local username="$1"
    
    echo "🔒 Application de la Gestion de Notifications Compatible SIP"
    
    # Configurer les paramètres Ne Pas Déranger
    sudo -u "$username" defaults write com.apple.ncprefs dnd_prefs -dict-add dndDisplayLock -bool true
    sudo -u "$username" defaults write com.apple.ncprefs dnd_prefs -dict-add dndDisplaySleep -bool true
    sudo -u "$username" defaults write com.apple.ncprefs dnd_prefs -dict-add dndMirrored -bool true
    
    # Désactiver les sons de notification pour la productivité
    sudo -u "$username" defaults write com.apple.sound.beep.feedback -bool false
    sudo -u "$username" defaults write com.apple.sound.uiaudio.enabled -int 0
    
    # Configurer les paramètres de bannière de notification
    sudo -u "$username" defaults write com.apple.ncprefs banner_setting -dict-add showOnLockScreen -bool false
    sudo -u "$username" defaults write com.apple.ncprefs banner_setting -dict-add showInNotificationCenter -bool false
    
    echo "✅ Gestion de notifications compatible SIP appliquée"
}

# Configurer les notifications en maintenant SIP
configure_sip_compatible_notifications() {
    local username="$1"
    
    echo "🔧 Configuration de Notifications Compatible SIP"
    
    # Activer les paramètres de notification optimisés
    sudo -u "$username" defaults write com.apple.ncprefs apps_setting -dict-add showOnLockScreen -bool true
    sudo -u "$username" defaults write com.apple.ncprefs apps_setting -dict-add showInNotificationCenter -bool true
    sudo -u "$username" defaults write com.apple.ncprefs apps_setting -dict-add showPreviews -int 2
    
    # Configurer le groupement de notifications
    sudo -u "$username" defaults write com.apple.ncprefs notification_group_settings -dict-add grouping -int 1
    
    # Redémarrer le service de notification
    sudo -u "$username" killall NotificationCenter 2>/dev/null || true
    
    echo "✅ Configuration de notifications compatible SIP appliquée"
}

Système de Gestion d'Entreprise des Notifications

#!/bin/bash

# Système de Gestion d'Entreprise des Notifications MacFleet
# Contrôle de communication complet, optimisation de productivité et amélioration d'expérience utilisateur

# Configuration
LOG_FILE="/var/log/macfleet_notification_management.log"
CONFIG_DIR="/etc/macfleet/notification_management"
POLICIES_DIR="$CONFIG_DIR/policies"
PROFILES_DIR="$CONFIG_DIR/profiles"
ANALYTICS_DIR="$CONFIG_DIR/analytics"
REPORTS_DIR="$CONFIG_DIR/reports"
COMPLIANCE_DIR="$CONFIG_DIR/compliance"
PRODUCTIVITY_DIR="$CONFIG_DIR/productivity"

# Politiques de gestion des notifications
declare -A NOTIFICATION_POLICIES=(
    ["focus_mode"]="interruptions_minimales,priorite_seulement,heures_silencieuses_programmees"
    ["productivity_optimized"]="groupement_intelligent,livraison_retardee,notifications_par_lot"
    ["enterprise_standard"]="alertes_securite_priorite,notifications_reunions,resumes_email"
    ["executive_minimal"]="critique_seulement,pas_social,appels_urgents_seulement"
    ["developer_focused"]="alertes_code,statut_compilation,systeme_critique_seulement"
    ["support_reactive"]="toutes_communications,livraison_instantanee,alertes_escalade"
    ["kiosk_restricted"]="alertes_systeme_seulement,pas_personnel,notifications_maintenance"
)

# Profils d'optimisation de productivité
declare -A PRODUCTIVITY_PROFILES=(
    ["deep_work"]="blocs_2_heures,pas_notifications,urgence_seulement"
    ["collaborative"]="messages_equipe,alertes_reunions,documents_partages"
    ["monitoring"]="statut_systeme,evenements_securite,alertes_performance"
    ["creative"]="apps_inspiration,feedback_design,interruptions_minimales"
    ["executive"]="mises_a_jour_calendrier,appels_urgents,communications_conseil"
)

# Priorité des canaux de communication
declare -A CHANNEL_PRIORITIES=(
    ["emergency"]="1"
    ["security"]="2"
    ["executive"]="3"
    ["team_lead"]="4"
    ["project"]="5"
    ["general"]="6"
    ["social"]="7"
    ["promotional"]="8"
)

# Configuration des applications d'entreprise
declare -A ENTERPRISE_APPS=(
    ["communication"]="Slack,Microsoft Teams,Zoom,Webex"
    ["productivity"]="Microsoft Office,Google Workspace,Notion,Trello"
    ["security"]="CrowdStrike,Okta,1Password,VPN Clients"
    ["development"]="Xcode,Visual Studio Code,GitHub Desktop,Docker"
    ["business"]="Salesforce,HubSpot,Tableau,Power BI"
)

# 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" "$PROFILES_DIR" "$ANALYTICS_DIR" "$REPORTS_DIR" "$COMPLIANCE_DIR" "$PRODUCTIVITY_DIR"; do
        if [[ ! -d "$dir" ]]; then
            mkdir -p "$dir"
            log_action "Répertoire créé: $dir"
        fi
    done
}

# Analyser le statut actuel des notifications
analyze_notification_status() {
    echo "=== Analyse du Système de Notifications ==="
    
    local current_user=$(echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ { print $3 }')
    local analysis_report="$ANALYTICS_DIR/notification_analysis_$(date '+%Y%m%d_%H%M%S').json"
    
    cat > "$analysis_report" << EOF
{
    "analysis_metadata": {
        "timestamp": "$(date -Iseconds)",
        "hostname": "$(hostname)",
        "current_user": "$current_user",
        "macos_version": "$(sw_vers -productVersion)"
    },
    "system_status": {
        "notification_center_running": $(pgrep -x "NotificationCenter" >/dev/null && echo "true" || echo "false"),
        "sip_status": "$(csrutil status | grep -o "enabled\|disabled")",
        "dnd_status": $(get_dnd_status "$current_user"),
        "user_session_active": $(test -n "$current_user" && test "$current_user" != "loginwindow" && echo "true" || echo "false")
    },
    "notification_settings": $(get_notification_settings "$current_user"),
    "app_permissions": $(analyze_app_notification_permissions "$current_user"),
    "productivity_metrics": $(calculate_notification_productivity_impact "$current_user"),
    "security_assessment": $(assess_notification_security "$current_user")
}
EOF

    log_action "✅ Analyse des notifications terminée: $analysis_report"
    echo "$analysis_report"
}

# Configurer les politiques de notification d'entreprise
configure_enterprise_notification_policy() {
    local policy_name="$1"
    local target_users="$2"
    local deployment_scope="$3"
    
    log_action "Configuration de la politique de notification d'entreprise: $policy_name"
    
    local policy_settings="${NOTIFICATION_POLICIES[$policy_name]}"
    if [[ -z "$policy_settings" ]]; then
        log_action "❌ Politique de notification inconnue: $policy_name"
        return 1
    fi
    
    echo "📋 Configuration de la Politique de Notification d'Entreprise: $policy_name"
    echo "Utilisateurs cibles: $target_users"
    echo "Portée de déploiement: $deployment_scope"
    
    # Créer la configuration de politique
    local policy_config="$POLICIES_DIR/notification_policy_${policy_name}.json"
    
    cat > "$policy_config" << EOF
{
    "policy_metadata": {
        "name": "$policy_name",
        "created": "$(date -Iseconds)",
        "settings": "$policy_settings",
        "target_users": "$target_users",
        "deployment_scope": "$deployment_scope"
    },
    "notification_rules": $(generate_notification_rules "$policy_name"),
    "app_configurations": $(generate_app_configurations "$policy_name"),
    "productivity_settings": $(generate_productivity_settings "$policy_name"),
    "security_controls": $(generate_security_controls "$policy_name")
}
EOF

    # Appliquer la politique selon la portée de déploiement
    case "$deployment_scope" in
        "user_specific")
            apply_user_specific_policy "$policy_name" "$target_users" "$policy_config"
            ;;
        "group_based")
            apply_group_based_policy "$policy_name" "$target_users" "$policy_config"
            ;;
        "fleet_wide")
            apply_fleet_wide_policy "$policy_name" "$policy_config"
            ;;
        *)
            log_action "⚠️  Portée de déploiement inconnue: $deployment_scope"
            return 1
            ;;
    esac
    
    log_action "✅ Politique de notification d'entreprise configurée: $policy_name"
    return 0
}

# Optimiser la productivité des notifications
optimize_notification_productivity() {
    local optimization_level="$1"
    local username="$2"
    local work_schedule="$3"
    
    log_action "Optimisation des notifications pour la productivité: niveau=$optimization_level, utilisateur=$username"
    
    local current_user=$(echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ { print $3 }')
    local target_user="${username:-$current_user}"
    
    echo "🚀 Optimisation de la Productivité des Notifications"
    echo "Niveau d'optimisation: $optimization_level"
    echo "Utilisateur cible: $target_user"
    echo "Horaire de travail: $work_schedule"
    
    case "$optimization_level" in
        "basic")
            apply_basic_productivity_optimizations "$target_user" "$work_schedule"
            ;;
        "advanced")
            apply_advanced_productivity_optimizations "$target_user" "$work_schedule"
            ;;
        "expert")
            apply_expert_productivity_optimizations "$target_user" "$work_schedule"
            ;;
        *)
            log_action "⚠️  Niveau d'optimisation inconnu: $optimization_level"
            return 1
            ;;
    esac
    
    # Configurer les sessions de concentration
    configure_focus_sessions "$target_user" "$work_schedule"
    
    # Configurer les analytics de notifications
    setup_notification_analytics "$target_user"
    
    # Appliquer le groupement intelligent des notifications
    configure_smart_notification_grouping "$target_user"
    
    log_action "✅ Optimisation de la productivité des notifications terminée"
    return 0
}

# Surveiller l'impact des notifications sur la productivité
monitor_notification_impact() {
    log_action "Démarrage de la surveillance de l'impact des notifications sur la productivité"
    
    local current_user=$(echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ { print $3 }')
    local impact_report="$PRODUCTIVITY_DIR/notification_impact_$(date '+%Y%m%d_%H%M%S').json"
    
    cat > "$impact_report" << EOF
{
    "impact_metadata": {
        "timestamp": "$(date -Iseconds)",
        "hostname": "$(hostname)",
        "monitored_user": "$current_user",
        "monitoring_period": "temps_reel"
    },
    "productivity_metrics": {
        "interruption_frequency": $(calculate_interruption_frequency "$current_user"),
        "focus_session_effectiveness": $(measure_focus_session_effectiveness "$current_user"),
        "notification_response_time": $(calculate_notification_response_time "$current_user"),
        "app_switching_frequency": $(measure_app_switching_frequency "$current_user")
    },
    "notification_analytics": {
        "total_notifications": $(count_daily_notifications "$current_user"),
        "critical_notifications": $(count_critical_notifications "$current_user"),
        "dismissed_without_action": $(count_dismissed_notifications "$current_user"),
        "notification_sources": $(analyze_notification_sources "$current_user")
    },
    "recommendations": {
        "optimization_suggestions": $(generate_optimization_suggestions "$current_user"),
        "policy_adjustments": $(suggest_policy_adjustments "$current_user"),
        "productivity_improvements": $(identify_productivity_improvements "$current_user")
    }
}
EOF

    log_action "✅ Surveillance de l'impact des notifications terminée: $impact_report"
    echo "$impact_report"
}

# Configurer les paramètres de notification spécifiques aux applications
configure_app_notification_settings() {
    local app_category="$1"
    local notification_level="$2"
    local username="$3"
    
    log_action "Configuration des notifications spécifiques aux applications: catégorie=$app_category, niveau=$notification_level"
    
    local current_user=$(echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ { print $3 }')
    local target_user="${username:-$current_user}"
    
    echo "📱 Configuration des Paramètres de Notification Spécifiques aux Applications"
    echo "Catégorie: $app_category"
    echo "Niveau de notification: $notification_level"
    echo "Utilisateur cible: $target_user"
    
    local apps="${ENTERPRISE_APPS[$app_category]}"
    if [[ -z "$apps" ]]; then
        log_action "⚠️  Catégorie d'application inconnue: $app_category"
        return 1
    fi
    
    # Analyser la liste d'applications
    IFS=',' read -ra APP_LIST <<< "$apps"
    
    for app in "${APP_LIST[@]}"; do
        configure_individual_app_notifications "$app" "$notification_level" "$target_user"
    done
    
    # Créer la configuration de catégorie d'application
    local app_config="$PROFILES_DIR/app_notifications_${app_category}.json"
    
    cat > "$app_config" << EOF
{
    "category_metadata": {
        "category": "$app_category",
        "notification_level": "$notification_level",
        "configured_user": "$target_user",
        "configured_time": "$(date -Iseconds)"
    },
    "configured_apps": $(echo "${apps}" | jq -R 'split(",")'),
    "notification_settings": $(get_category_notification_settings "$notification_level"),
    "productivity_impact": $(assess_category_productivity_impact "$app_category")
}
EOF

    log_action "✅ Paramètres de notification spécifiques aux applications configurés pour la catégorie: $app_category"
    return 0
}

# Fonction d'exécution principale
main() {
    local action="${1:-status}"
    local parameter="$2"
    local additional_param="$3"
    local extra_param="$4"
    
    log_action "=== Gestion des Notifications MacFleet Démarrée ==="
    log_action "Action: $action"
    log_action "Paramètre: ${parameter:-N/A}"
    
    setup_directories
    
    case "$action" in
        "disable")
            disable_notification_center
            ;;
        "enable")
            enable_notification_center
            ;;
        "analyze")
            analyze_notification_status
            ;;
        "policy")
            if [[ -z "$parameter" || -z "$additional_param" ]]; then
                echo "Politiques de notification disponibles:"
                for policy in "${!NOTIFICATION_POLICIES[@]}"; do
                    echo "  - $policy: ${NOTIFICATION_POLICIES[$policy]}"
                done
                echo ""
                echo "Usage: $0 policy <nom_politique> <utilisateurs_cibles> [portee_deploiement]"
                echo "Portées de déploiement: user_specific, group_based, fleet_wide"
                exit 1
            fi
            configure_enterprise_notification_policy "$parameter" "$additional_param" "$extra_param"
            ;;
        "optimize")
            if [[ -z "$parameter" ]]; then
                echo "Niveaux d'optimisation: basic, advanced, expert"
                echo "Horaires de travail: business_hours, flexible, 24x7"
                echo ""
                echo "Usage: $0 optimize <niveau> [nom_utilisateur] [horaire_travail]"
                exit 1
            fi
            optimize_notification_productivity "$parameter" "$additional_param" "$extra_param"
            ;;
        "monitor")
            monitor_notification_impact
            ;;
        "apps")
            if [[ -z "$parameter" || -z "$additional_param" ]]; then
                echo "Catégories d'applications disponibles:"
                for category in "${!ENTERPRISE_APPS[@]}"; do
                    echo "  - $category: ${ENTERPRISE_APPS[$category]}"
                done
                echo ""
                echo "Niveaux de notification: critical_only, important, standard, all, disabled"
                echo "Usage: $0 apps <catégorie> <niveau_notification> [nom_utilisateur]"
                exit 1
            fi
            configure_app_notification_settings "$parameter" "$additional_param" "$extra_param"
            ;;
        "status")
            analyze_notification_status
            ;;
        *)
            echo "Usage: $0 {disable|enable|analyze|policy|optimize|monitor|apps|status}"
            echo "  disable     - Désactiver le centre de notifications (avec considérations SIP)"
            echo "  enable      - Activer le centre de notifications"
            echo "  analyze     - Analyser le statut actuel du système de notifications"
            echo "  policy      - Configurer les politiques de notification d'entreprise"
            echo "  optimize    - Optimiser les notifications pour la productivité"
            echo "  monitor     - Surveiller l'impact des notifications sur la productivité"
            echo "  apps        - Configurer les paramètres de notification spécifiques aux applications"
            echo "  status      - Vérifier le statut du système de notifications"
            exit 1
            ;;
    esac
    
    log_action "=== Opération de gestion des notifications terminée ==="
}

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

Fonctionnalités Avancées de Gestion des Notifications

Sessions de Concentration Intelligentes

#!/bin/bash

# Gestion de sessions de concentration alimentée par IA
configure_intelligent_focus_sessions() {
    local username="$1"
    local productivity_goals="$2"
    
    echo "🧠 Configuration des Sessions de Concentration Intelligentes"
    
    local focus_config="$PRODUCTIVITY_DIR/focus_sessions_${username}.json"
    
    cat > "$focus_config" << EOF
{
    "focus_session_config": {
        "user": "$username",
        "productivity_goals": "$productivity_goals",
        "session_types": {
            "deep_work": {
                "duration": 120,
                "break_duration": 15,
                "allowed_notifications": ["urgence", "securite"],
                "blocked_apps": ["social", "divertissement"],
                "productivity_score_weight": 0.8
            },
            "collaborative": {
                "duration": 60,
                "break_duration": 10,
                "allowed_notifications": ["communication_equipe", "calendrier"],
                "blocked_apps": ["social_personnel"],
                "productivity_score_weight": 0.6
            },
            "creative": {
                "duration": 90,
                "break_duration": 20,
                "allowed_notifications": ["inspiration", "outils_creatifs"],
                "blocked_apps": ["outils_analytiques"],
                "productivity_score_weight": 0.7
            }
        },
        "adaptive_learning": {
            "track_productivity_patterns": true,
            "adjust_session_length": true,
            "optimize_break_timing": true,
            "personalize_notification_filtering": true
        }
    }
}
EOF

    echo "✅ Sessions de concentration intelligentes configurées"
}

# Analytics de productivité en temps réel
real_time_productivity_analytics() {
    echo "📊 Analytics de Productivité en Temps Réel"
    
    local analytics_script="$PRODUCTIVITY_DIR/real_time_analytics.sh"
    
    cat > "$analytics_script" << 'EOF'
#!/bin/bash

# Analytics de productivité des notifications en temps réel

while true; do
    CURRENT_USER=$(echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ { print $3 }')
    
    if [[ -n "$CURRENT_USER" && "$CURRENT_USER" != "loginwindow" ]]; then
        # Suivre les interruptions de notifications
        NOTIFICATION_COUNT=$(log show --predicate 'subsystem == "com.apple.notificationcenter"' --last 1h | wc -l)
        
        # Calculer le score de concentration
        FOCUS_SCORE=$(calculate_real_time_focus_score "$CURRENT_USER" "$NOTIFICATION_COUNT")
        
        # Générer des insights de productivité
        PRODUCTIVITY_INSIGHTS=$(generate_real_time_insights "$CURRENT_USER" "$FOCUS_SCORE")
        
        # Enregistrer les analytics
        echo "$(date): User=$CURRENT_USER, Notifications=$NOTIFICATION_COUNT, Focus Score=$FOCUS_SCORE" >> /var/log/macfleet_productivity_analytics.log
        
        # Optimisation adaptative
        if [[ $FOCUS_SCORE -lt 60 ]]; then
            apply_adaptive_optimization "$CURRENT_USER"
        fi
    fi
    
    sleep 300  # Vérifier toutes les 5 minutes
done
EOF

    chmod +x "$analytics_script"
    echo "📈 Script d'analytics en temps réel créé"
}

Fonctionnalités d'Intégration d'Entreprise

🔗 Intégration Système

  • Intégration Active Directory pour politiques de notification basées utilisateur
  • Authentification LDAP pour gestion des permissions de notification
  • Intégration SIEM avec priorisation des notifications de sécurité
  • Synchronisation plateformes productivité (intégration Slack, Teams, Asana)

📱 Gestion de Flotte

  • Déploiement de politiques centralisé à travers les appareils d'entreprise
  • Profils de notification basés rôle avec attribution automatique
  • Gestion de configuration en lot avec capacités de rollback
  • Surveillance de conformité avec rapports automatisés

🎯 Optimisation Expérience Utilisateur

  • Filtrage de notifications alimenté par IA avec algorithmes d'apprentissage
  • Livraison contextuelle basée sur activité utilisateur et calendrier
  • Analytics de productivité avec insights personnalisés
  • Automatisation de sessions de concentration avec gestion intelligente des interruptions

🛡️ Sécurité et Confidentialité

  • Opérations compatibles SIP maintenant la sécurité système
  • Analytics préservant la confidentialité avec minimisation des données
  • Routage sécurisé des notifications avec chiffrement en transit
  • Support cadres de conformité (GDPR, HIPAA, SOX, PCI DSS)

Notes Importantes

  • System Integrity Protection (SIP) doit rester activé pour la sécurité
  • Méthodes de gestion alternatives fournies pour systèmes avec SIP activé
  • Considérations de confidentialité utilisateur essentielles pour surveillance notifications
  • Optimisation de productivité nécessite équilibre soigneux avec besoins de communication
  • Évaluation régulière nécessaire pour maintenir politiques de notification optimales
  • Exigences de conformité peuvent remplacer optimisations de productivité