Initialisation depot
This commit is contained in:
4
Migration/.gitignore
vendored
Normal file
4
Migration/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
*.csv
|
||||
inventory.yml
|
||||
import_dns_samba.sh
|
||||
|
||||
18
Migration/Ansible/ansible.cfg
Normal file
18
Migration/Ansible/ansible.cfg
Normal file
@@ -0,0 +1,18 @@
|
||||
# Ansible Configuration for Samba4 DC Installation
|
||||
[defaults]
|
||||
inventory = inventory.yml
|
||||
host_key_checking = False
|
||||
timeout = 30
|
||||
gather_timeout = 30
|
||||
fact_caching = memory
|
||||
fact_caching_timeout = 3600
|
||||
|
||||
# Display settings
|
||||
stdout_callback = yaml
|
||||
bin_ansible_callbacks = True
|
||||
|
||||
# SSH settings
|
||||
[ssh_connection]
|
||||
ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o UserKnownHostsFile=/dev/null
|
||||
pipelining = True
|
||||
retries = 3
|
||||
65
Migration/Ansible/diagnostic.yml
Normal file
65
Migration/Ansible/diagnostic.yml
Normal file
@@ -0,0 +1,65 @@
|
||||
---
|
||||
# Diagnostic Playbook for Troubleshooting
|
||||
- name: System Diagnostic
|
||||
hosts: all
|
||||
become: yes
|
||||
gather_facts: yes
|
||||
|
||||
tasks:
|
||||
- name: Display system information
|
||||
debug:
|
||||
msg:
|
||||
- "Distribution: {{ ansible_distribution }} {{ ansible_distribution_version }}"
|
||||
- "Architecture: {{ ansible_architecture }}"
|
||||
- "Kernel: {{ ansible_kernel }}"
|
||||
- "Service Manager: {{ ansible_service_mgr }}"
|
||||
- "Python Version: {{ ansible_python_version }}"
|
||||
|
||||
- name: Check available services
|
||||
service_facts:
|
||||
|
||||
- name: Display logging services
|
||||
debug:
|
||||
msg: "Available logging services: {{ ansible_facts.services.keys() | select('match', '.*log.*') | list }}"
|
||||
|
||||
- name: Check if rsyslog package is installed
|
||||
package_facts:
|
||||
manager: apt
|
||||
|
||||
- name: Display rsyslog package info
|
||||
debug:
|
||||
msg: "Rsyslog installed: {{ 'rsyslog' in ansible_facts.packages }}"
|
||||
|
||||
- name: Test basic connectivity
|
||||
ping:
|
||||
|
||||
- name: Check disk space
|
||||
debug:
|
||||
msg: "Available space: {{ ansible_mounts | selectattr('mount', 'equalto', '/') | map(attribute='size_available') | first | human_readable }}"
|
||||
|
||||
- name: Create diagnostic script
|
||||
template:
|
||||
src: system-diagnostic.sh.j2
|
||||
dest: /tmp/diagnostic.sh
|
||||
mode: '0755'
|
||||
delegate_to: localhost
|
||||
run_once: true
|
||||
|
||||
- name: Run diagnostic on target
|
||||
shell: |
|
||||
echo "=== System Information ==="
|
||||
uname -a
|
||||
echo ""
|
||||
echo "=== Distribution ==="
|
||||
cat /etc/os-release 2>/dev/null || echo "No os-release file"
|
||||
echo ""
|
||||
echo "=== Services ==="
|
||||
systemctl list-units --type=service --state=active | head -10 || echo "No systemctl"
|
||||
echo ""
|
||||
echo "=== Packages ==="
|
||||
dpkg -l | grep rsyslog || echo "No rsyslog package found"
|
||||
register: diagnostic_output
|
||||
|
||||
- name: Display diagnostic output
|
||||
debug:
|
||||
var: diagnostic_output.stdout_lines
|
||||
31
Migration/Ansible/install-samba4.yml
Normal file
31
Migration/Ansible/install-samba4.yml
Normal file
@@ -0,0 +1,31 @@
|
||||
---
|
||||
# Samba4 DC Installation Playbook
|
||||
- name: Install and configure Samba4 Domain Controller
|
||||
hosts: samba_servers
|
||||
become: yes
|
||||
gather_facts: yes
|
||||
|
||||
pre_tasks:
|
||||
- name: Verify target server requirements
|
||||
assert:
|
||||
that:
|
||||
- ansible_distribution == "Debian" or ansible_distribution == "Ubuntu"
|
||||
- ansible_python_version is version('3.6', '>=')
|
||||
fail_msg: "This playbook requires Debian/Ubuntu with Python 3.6+"
|
||||
success_msg: "Server requirements verified"
|
||||
|
||||
roles:
|
||||
- system
|
||||
- nfs
|
||||
- samba4-dc
|
||||
|
||||
post_tasks:
|
||||
- name: Final verification
|
||||
block:
|
||||
- name: Display installation summary
|
||||
debug:
|
||||
msg:
|
||||
- "Samba4 DC installation completed successfully!"
|
||||
- "Domain: {{ samba_realm }}"
|
||||
- "NetBIOS: {{ samba_domain }}"
|
||||
|
||||
26
Migration/Ansible/inventory.sample
Normal file
26
Migration/Ansible/inventory.sample
Normal file
@@ -0,0 +1,26 @@
|
||||
---
|
||||
# Ansible Inventory for Samba4 DC Installation
|
||||
all:
|
||||
children:
|
||||
samba_servers:
|
||||
hosts:
|
||||
dc01:
|
||||
ansible_host: ADDRIP
|
||||
ansible_user: installer
|
||||
ansible_ssh_private_key_file: ~/.ssh/id_ed25519
|
||||
# Server configuration
|
||||
target_hostname: HOSTNAME
|
||||
# Samba4 configuration
|
||||
samba_realm: domain.tld
|
||||
samba_domain: DOMAIN
|
||||
samba_netbios_name: HOSTNAME
|
||||
samba_admin_password: ADMIN-PASSWORD
|
||||
samba_domain_sid: DOMAIN-SID
|
||||
dns_servers:
|
||||
- 127.0.0.1
|
||||
- 8.8.8.8
|
||||
# NFS configuration
|
||||
nfs_server: NFS-SERVER
|
||||
nfs_share: NFS-PATH
|
||||
nfs_mount_point: /backup
|
||||
backup_dir: /backup/samba
|
||||
41
Migration/Ansible/roles/nfs/tasks/main.yml
Normal file
41
Migration/Ansible/roles/nfs/tasks/main.yml
Normal file
@@ -0,0 +1,41 @@
|
||||
---
|
||||
# NFS Client Role - Main Tasks
|
||||
|
||||
- name: Ensure required variables are present
|
||||
assert:
|
||||
that:
|
||||
- nfs_mounts is defined or (nfs_server is defined and nfs_share is defined and nfs_mount_point is defined)
|
||||
fail_msg: "You must define either 'nfs_mounts' (a list of mounts) or the trio 'nfs_server', 'nfs_share' and 'nfs_mount_point'."
|
||||
|
||||
- name: Install nfs-common package (Debian/Ubuntu)
|
||||
apt:
|
||||
name: nfs-common
|
||||
state: present
|
||||
become: true
|
||||
|
||||
- name: Build `nfs_mounts` list from single-vars if needed
|
||||
set_fact:
|
||||
nfs_mounts: "{{ [ {'server': nfs_server, 'share': nfs_share, 'path': nfs_mount_point, 'options': (nfs_options | default(omit)) } ] }}"
|
||||
when: nfs_mounts is not defined
|
||||
|
||||
- name: Validate each NFS server is reachable (port 2049)
|
||||
wait_for:
|
||||
host: "{{ item.server }}"
|
||||
port: 2049
|
||||
timeout: 5
|
||||
state: started
|
||||
loop: "{{ nfs_mounts }}"
|
||||
loop_control:
|
||||
label: "{{ item.server }}:{{ item.share }}"
|
||||
|
||||
- name: Ensure the NFS share is exported by the server
|
||||
shell: |
|
||||
showmount -e {{ item.server }} | awk 'NR>1 {print $1}' | grep -x -- "{{ item.share }}"
|
||||
register: showmount_check
|
||||
failed_when: showmount_check.rc != 0
|
||||
changed_when: false
|
||||
loop: "{{ nfs_mounts }}"
|
||||
loop_control:
|
||||
label: "{{ item.server }}:{{ item.share }}"
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
- name: Configure DNS forwarders
|
||||
lineinfile:
|
||||
path: /etc/samba/smb.conf
|
||||
regexp: '^(\s*)dns forwarder\s*='
|
||||
line: ' dns forwarder = 8.8.8.8 1.1.1.1'
|
||||
insertafter: '^\[global\]'
|
||||
|
||||
69
Migration/Ansible/roles/samba4-dc/tasks/dns_config.yml
Normal file
69
Migration/Ansible/roles/samba4-dc/tasks/dns_config.yml
Normal file
@@ -0,0 +1,69 @@
|
||||
---
|
||||
# DNS Configuration and Reverse DNS Setup
|
||||
- name: Wait for Samba DNS to be ready
|
||||
wait_for:
|
||||
port: 53
|
||||
host: 127.0.0.1
|
||||
delay: 5
|
||||
timeout: 30
|
||||
|
||||
- name: Check if reverse DNS zone already exists
|
||||
command: >
|
||||
samba-tool dns zonelist 127.0.0.1
|
||||
--username=Administrator --password={{ samba_admin_password }}
|
||||
register: existing_zones
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
|
||||
- name: Create reverse DNS zone
|
||||
command: >
|
||||
samba-tool dns zonecreate 127.0.0.1 100.168.192.in-addr.arpa
|
||||
--username=Administrator --password={{ samba_admin_password }}
|
||||
register: reverse_zone
|
||||
changed_when: reverse_zone.rc == 0
|
||||
failed_when: reverse_zone.rc != 0 and "already exists" not in reverse_zone.stderr
|
||||
when: "'100.168.192.in-addr.arpa' not in existing_zones.stdout"
|
||||
|
||||
- name: Check existing NS records in reverse zone
|
||||
command: >
|
||||
samba-tool dns query 127.0.0.1 100.168.192.in-addr.arpa @ NS
|
||||
--username=Administrator --password={{ samba_admin_password }}
|
||||
register: existing_ns_records
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
|
||||
- name: Add NS record for reverse zone
|
||||
command: >
|
||||
samba-tool dns add 127.0.0.1 100.168.192.in-addr.arpa @ NS {{ target_hostname }}.{{ samba_realm }}.
|
||||
--username=Administrator --password={{ samba_admin_password }}
|
||||
register: dns_ns_record
|
||||
changed_when: dns_ns_record.rc == 0
|
||||
failed_when: dns_ns_record.rc != 0 and "already exists" not in dns_ns_record.stderr
|
||||
when: "target_hostname + '.' + samba_realm + '.' not in existing_ns_records.stdout"
|
||||
|
||||
- name: Get current server IP address for DNS record
|
||||
shell: |
|
||||
ip route get 8.8.8.8 | grep -oP 'src \K\S+' | head -1
|
||||
register: current_server_ip
|
||||
changed_when: false
|
||||
|
||||
- name: Extract host part from IP address
|
||||
set_fact:
|
||||
ip_host_part: "{{ current_server_ip.stdout.split('.')[3] }}"
|
||||
|
||||
- name: Check existing PTR records in reverse zone
|
||||
command: >
|
||||
samba-tool dns query 127.0.0.1 100.168.192.in-addr.arpa {{ ip_host_part }} PTR
|
||||
--username=Administrator --password={{ samba_admin_password }}
|
||||
register: existing_ptr_records
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
|
||||
- name: Add PTR record for reverse zone
|
||||
command: >
|
||||
samba-tool dns add 127.0.0.1 100.168.192.in-addr.arpa {{ ip_host_part }} PTR {{ target_hostname }}.{{ samba_realm }}.
|
||||
--username=Administrator --password={{ samba_admin_password }}
|
||||
register: dns_ptr_record
|
||||
changed_when: dns_ptr_record.rc == 0
|
||||
failed_when: dns_ptr_record.rc != 0 and "already exists" not in dns_ptr_record.stderr
|
||||
when: "target_hostname + '.' + samba_realm + '.' not in existing_ptr_records.stdout"
|
||||
36
Migration/Ansible/roles/samba4-dc/tasks/install_samba.yml
Normal file
36
Migration/Ansible/roles/samba4-dc/tasks/install_samba.yml
Normal file
@@ -0,0 +1,36 @@
|
||||
---
|
||||
# Samba4 installation tasks
|
||||
- name: Check if Samba domain is already provisioned
|
||||
stat:
|
||||
path: /var/lib/samba/private/sam.ldb
|
||||
register: samba_provisioned
|
||||
|
||||
- name: Provision Samba4 domain
|
||||
command: >
|
||||
samba-tool domain provision
|
||||
--use-rfc2307
|
||||
--realm={{ samba_realm }}
|
||||
--domain={{ samba_domain }}
|
||||
--adminpass={{ samba_admin_password }}
|
||||
--server-role=dc
|
||||
--dns-backend=SAMBA_INTERNAL
|
||||
--domain-sid={{ samba_domain_sid }}
|
||||
when: not samba_provisioned.stat.exists
|
||||
|
||||
- name: Copy Kerberos configuration
|
||||
copy:
|
||||
src: /var/lib/samba/private/krb5.conf
|
||||
dest: /etc/krb5.conf
|
||||
remote_src: yes
|
||||
backup: yes
|
||||
|
||||
- name: Enable and start samba-ad-dc service
|
||||
systemd:
|
||||
name: samba-ad-dc
|
||||
enabled: yes
|
||||
state: started
|
||||
daemon_reload: yes
|
||||
|
||||
- name: Include DNS configuration tasks
|
||||
include_tasks: dns_config.yml
|
||||
|
||||
15
Migration/Ansible/roles/samba4-dc/tasks/main.yml
Normal file
15
Migration/Ansible/roles/samba4-dc/tasks/main.yml
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
- name: Include pre-installation tasks
|
||||
include_tasks: pre_install.yml
|
||||
|
||||
- name: Include network configuration
|
||||
include_tasks: network.yml
|
||||
|
||||
- name: Include Samba4 installation
|
||||
include_tasks: install_samba.yml
|
||||
|
||||
- name: Include Samba4 configuration
|
||||
include_tasks: configure_samba.yml
|
||||
|
||||
- name: Include post-installation tasks
|
||||
include_tasks: post_install.yml
|
||||
9
Migration/Ansible/roles/samba4-dc/tasks/network.yml
Normal file
9
Migration/Ansible/roles/samba4-dc/tasks/network.yml
Normal file
@@ -0,0 +1,9 @@
|
||||
---
|
||||
# Network configuration tasks
|
||||
|
||||
- name: Configure DNS resolution
|
||||
template:
|
||||
src: resolv.conf.j2
|
||||
dest: /etc/resolv.conf
|
||||
backup: yes
|
||||
|
||||
38
Migration/Ansible/roles/samba4-dc/tasks/post_install.yml
Normal file
38
Migration/Ansible/roles/samba4-dc/tasks/post_install.yml
Normal file
@@ -0,0 +1,38 @@
|
||||
---
|
||||
- name: Create backup script
|
||||
template:
|
||||
src: samba-backup.sh.j2
|
||||
dest: /usr/local/bin/samba-backup.sh
|
||||
mode: '0755'
|
||||
|
||||
- name: Create restore script
|
||||
template:
|
||||
src: samba-restore.sh.j2
|
||||
dest: /usr/local/bin/samba-restore.sh
|
||||
mode: '0755'
|
||||
|
||||
- name: Create ChangeNextRid script
|
||||
template:
|
||||
src: samba-changenextrid.sh.j2
|
||||
dest: /usr/local/bin/samba-changenextrid.sh
|
||||
mode: '0755'
|
||||
|
||||
- name: Setup NFS backup storage
|
||||
include_role:
|
||||
name: nfs
|
||||
vars:
|
||||
nfs_mounts:
|
||||
- server: "192.168.100.210"
|
||||
share: "/mnt/zpool20T/data-encrypt/NFS"
|
||||
path: "/backup"
|
||||
options: "rw,sync,hard,intr,rsize=8192,wsize=8192"
|
||||
subdirs:
|
||||
- "samba"
|
||||
|
||||
- name: Setup backup cron job
|
||||
cron:
|
||||
name: "Samba4 weekly backup"
|
||||
minute: "0"
|
||||
hour: "2"
|
||||
weekday: "0"
|
||||
job: "/usr/local/bin/samba-backup.sh"
|
||||
92
Migration/Ansible/roles/samba4-dc/tasks/pre_install.yml
Normal file
92
Migration/Ansible/roles/samba4-dc/tasks/pre_install.yml
Normal file
@@ -0,0 +1,92 @@
|
||||
---
|
||||
# Pre-installation tasks
|
||||
- name: Install required Samba packages
|
||||
apt:
|
||||
name:
|
||||
- samba
|
||||
- samba-dsdb-modules
|
||||
- samba-vfs-modules
|
||||
- winbind
|
||||
- libnss-winbind
|
||||
- libpam-winbind
|
||||
- krb5-config
|
||||
- krb5-user
|
||||
- dnsutils
|
||||
- acl
|
||||
- attr
|
||||
- ldb-tools
|
||||
- smbclient
|
||||
state: present
|
||||
|
||||
- name: Stop default Samba services
|
||||
systemd:
|
||||
name: "{{ item }}"
|
||||
state: stopped
|
||||
enabled: no
|
||||
loop:
|
||||
- smbd
|
||||
- nmbd
|
||||
- winbind
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Mask default Samba services to prevent conflicts
|
||||
systemd:
|
||||
name: "{{ item }}"
|
||||
masked: yes
|
||||
loop:
|
||||
- smbd
|
||||
- nmbd
|
||||
- winbind
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Check if server is already an Active Directory Domain Controller
|
||||
shell: |
|
||||
if [ -f /etc/samba/smb.conf ]; then
|
||||
grep -i "server role.*active directory domain controller" /etc/samba/smb.conf || echo "not_ad_dc"
|
||||
else
|
||||
echo "no_config"
|
||||
fi
|
||||
register: samba_role_check
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
|
||||
- name: Display current Samba role status
|
||||
debug:
|
||||
msg: |
|
||||
{% if 'active directory domain controller' in samba_role_check.stdout.lower() %}
|
||||
✅ Server is already configured as Active Directory Domain Controller
|
||||
⚠️ Skipping backup and cleanup to preserve existing AD configuration
|
||||
{% else %}
|
||||
ℹ️ Server is not configured as AD DC ({{ samba_role_check.stdout }})
|
||||
🔄 Will backup existing config and clean databases
|
||||
{% endif %}
|
||||
|
||||
- name: Backup existing Samba configuration
|
||||
copy:
|
||||
src: /etc/samba/smb.conf
|
||||
dest: /etc/samba/smb.conf.orig
|
||||
remote_src: yes
|
||||
backup: yes
|
||||
ignore_errors: yes
|
||||
when: "'active directory domain controller' not in samba_role_check.stdout.lower()"
|
||||
|
||||
- name: Clean existing Samba databases
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: absent
|
||||
loop:
|
||||
- /var/lib/samba/private
|
||||
- /var/cache/samba
|
||||
- /etc/samba/smb.conf
|
||||
ignore_errors: yes
|
||||
when: "'active directory domain controller' not in samba_role_check.stdout.lower()"
|
||||
|
||||
- name: Recreate Samba directories
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
loop:
|
||||
- /var/lib/samba
|
||||
- /var/cache/samba
|
||||
when: "'active directory domain controller' not in samba_role_check.stdout.lower()"
|
||||
@@ -0,0 +1,6 @@
|
||||
# DNS resolver configuration
|
||||
{% for dns_server in dns_servers %}
|
||||
nameserver {{ dns_server }}
|
||||
{% endfor %}
|
||||
search {{ samba_realm }}
|
||||
domain {{ samba_realm }}
|
||||
@@ -0,0 +1,83 @@
|
||||
#!/bin/bash
|
||||
# Samba4 Backup Script
|
||||
# Generated by Ansible
|
||||
|
||||
TIMESTAMP=$(date '+%Y-%m-%d_%H-%M-%S')
|
||||
DATE=$(date +%Y%m%d_%H%M%S) # Kept for compatibility
|
||||
HOSTNAME="{{ target_hostname }}"
|
||||
NFS_SERVER="{{ nfs_server | default('192.168.100.210') }}"
|
||||
NFS_MOUNT="/backup"
|
||||
BACKUP_BASE_DIR="{{ backup_dir | default('/backup/samba') }}"
|
||||
RETENTION_DAYS="28"
|
||||
|
||||
# End of configuration
|
||||
|
||||
BACKUP_FILE="$BACKUP_BASE_DIR/$HOSTNAME-$TIMESTAMP.tgz"
|
||||
|
||||
{% raw %}
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo -e "${CYAN}🔄 Samba4 Backup Script"
|
||||
echo "==============================${NC}"
|
||||
|
||||
# Function to check NFS availability
|
||||
echo "Checking NFS availability..."
|
||||
# Test 1: Check if backup directory is mounted
|
||||
if ! mountpoint -q "$NFS_MOUNT"; then
|
||||
echo -e "${RED}❌ ERROR: NFS mount point $NFS_MOUNT is not mounted!${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Starting backup : $BACKUP_FILE" >> "$BACKUP_BASE_DIR/backup.log"
|
||||
|
||||
# Create backup folder
|
||||
mkdir -p "$BACKUP_BASE_DIR"
|
||||
if [ ! -d "$BACKUP_BASE_DIR" ]; then
|
||||
echo -e "${RED}❌ ERROR: cannot create $BACKUP_BASE_DIR${NC}"
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] ERROR: cannot create $BACKUP_BASE_DIR" >> "$BACKUP_BASE_DIR/backup.log"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# Create backup file
|
||||
touch $BACKUP_FILE
|
||||
if [ ! -f "$BACKUP_FILE" ]; then
|
||||
echo -e "${RED}❌ ERROR: Cannot create backup file${NC}"
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] ERROR: Cannot create backup file" >> "$BACKUP_BASE_DIR/backup.log"
|
||||
exit 3
|
||||
fi
|
||||
|
||||
# Stop samba
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Stopping Samba service" >> "$BACKUP_BASE_DIR/backup.log"
|
||||
systemctl stop samba-ad-dc
|
||||
|
||||
tar -czf "$BACKUP_FILE" \
|
||||
/var/lib/samba \
|
||||
/etc/samba \
|
||||
/etc/krb5.conf \
|
||||
/etc/resolv.conf 2>/dev/null
|
||||
|
||||
# Restart Samba
|
||||
echo -e "${YELLOW}🔄 Restarting Samba service${NC}"
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Starting Samba service" >> "$BACKUP_BASE_DIR/backup.log"
|
||||
systemctl start samba-ad-dc
|
||||
|
||||
# Wait for Samba to be fully operational
|
||||
sleep 10
|
||||
if ! systemctl is-active --quiet samba-ad-dc; then
|
||||
echo -e "${YELLOW}⚠️ WARNING: Samba service may not be fully operational${NC}"
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] WARNING: Samba service may not be fully operational" >> "$BACKUP_BASE_DIR/backup.log"
|
||||
fi
|
||||
|
||||
|
||||
# Clean old backups
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Clean old backups" >> "$BACKUP_BASE_DIR/backup.log"
|
||||
find "$BACKUP_BASE_DIR" -type f -mtime +$RETENTION_DAYS -delete
|
||||
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Backup done" >> "$BACKUP_BASE_DIR/backup.log"
|
||||
echo -e "${GREEN}Backup done${NC}"
|
||||
{% endraw %}
|
||||
@@ -0,0 +1,109 @@
|
||||
#!/bin/bash
|
||||
# Script to modify the next RID
|
||||
|
||||
# Configuration variables from Ansible
|
||||
TARGET_HOSTNAME="{{ target_hostname }}"
|
||||
DOMAIN_DN="{{ samba_realm.split('.') | map('regex_replace', '^(.*)$', 'DC=\\1') | join(',') }}"
|
||||
|
||||
{% raw %}
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
CYAN='\033[0;36m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
set_next_rid() {
|
||||
local new_rid=$1
|
||||
local pool_size=500
|
||||
|
||||
if [ -z "$new_rid" ]; then
|
||||
echo -e "${RED}Usage: set_next_rid <new_rid>${NC}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ $new_rid -lt 1000 ]; then
|
||||
echo -e "${RED}❌ Error: RID must be >= 1000 (RIDs < 1000 are reserved for system)${NC}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo -e "${CYAN}🎯 Current configuration:${NC}"
|
||||
ldbsearch -H /var/lib/samba/private/sam.ldb \
|
||||
-b "CN=RID Set,CN=${TARGET_HOSTNAME},OU=Domain Controllers,${DOMAIN_DN}" \
|
||||
rIDNextRID rIDAllocationPool | grep -E "(rIDNextRID|rIDAllocationPool)"
|
||||
|
||||
echo ""
|
||||
echo -e "${YELLOW}🔄 New configuration:${NC}"
|
||||
echo -e " ${CYAN}rIDNextRID:${NC} $new_rid"
|
||||
echo -e " ${CYAN}rIDAllocationPool:${NC} $new_rid-$((new_rid + pool_size - 1))"
|
||||
echo ""
|
||||
|
||||
echo -n -e "${YELLOW}Continue? (y/N): ${NC}"
|
||||
read confirm
|
||||
if [ "$confirm" != "y" ]; then
|
||||
echo -e "${YELLOW}🚫 Cancelled${NC}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo -e "${CYAN}🛑 Stopping Samba...${NC}"
|
||||
systemctl stop samba-ad-dc
|
||||
|
||||
# Create LDIF file
|
||||
cat > /tmp/set-next-rid.ldif << EOF
|
||||
dn: CN=RID Set,CN=${TARGET_HOSTNAME},OU=Domain Controllers,${DOMAIN_DN}
|
||||
changetype: modify
|
||||
replace: rIDNextRID
|
||||
rIDNextRID: $new_rid
|
||||
-
|
||||
replace: rIDAllocationPool
|
||||
rIDAllocationPool: $new_rid-$((new_rid + pool_size - 1))
|
||||
-
|
||||
replace: rIDPreviousAllocationPool
|
||||
rIDPreviousAllocationPool: $new_rid-$((new_rid + pool_size - 1))
|
||||
EOF
|
||||
|
||||
# Apply changes
|
||||
if ldbmodify -H /var/lib/samba/private/sam.ldb /tmp/set-next-rid.ldif; then
|
||||
echo -e "${GREEN}✅ RID modified successfully${NC}"
|
||||
else
|
||||
echo -e "${RED}❌ Error during modification${NC}"
|
||||
systemctl start samba-ad-dc
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo -e "${CYAN}🚀 Restarting Samba...${NC}"
|
||||
systemctl start samba-ad-dc
|
||||
|
||||
# Verification
|
||||
sleep 3
|
||||
echo ""
|
||||
echo -e "${CYAN}🔍 Verification:${NC}"
|
||||
ldbsearch -H /var/lib/samba/private/sam.ldb \
|
||||
-b "CN=RID Set,CN=${TARGET_HOSTNAME},OU=Domain Controllers,${DOMAIN_DN}" \
|
||||
rIDNextRID rIDAllocationPool | grep -E "(rIDNextRID|rIDAllocationPool)"
|
||||
|
||||
rm -f /tmp/set-next-rid.ldif
|
||||
}
|
||||
|
||||
# Usage
|
||||
case "$1" in
|
||||
"show")
|
||||
echo -e "${CYAN}📊 Current RID status:${NC}"
|
||||
ldbsearch -H /var/lib/samba/private/sam.ldb \
|
||||
-b "CN=RID Set,CN=${TARGET_HOSTNAME},OU=Domain Controllers,${DOMAIN_DN}" \
|
||||
rIDNextRID rIDAllocationPool rIDUsedPool | \
|
||||
grep -E "(rIDNextRID|rIDAllocationPool|rIDUsedPool)"
|
||||
;;
|
||||
"set")
|
||||
set_next_rid $2
|
||||
;;
|
||||
*)
|
||||
echo -e "${YELLOW}Usage: $0 {show|set <new_rid>}${NC}"
|
||||
echo ""
|
||||
echo -e "${CYAN}Examples:${NC}"
|
||||
echo -e " ${GREEN}$0 show${NC} # Show current status"
|
||||
echo -e " ${GREEN}$0 set 2000${NC} # Force next RID to 2000"
|
||||
echo -e " ${GREEN}$0 set 5000${NC} # Force next RID to 5000"
|
||||
;;
|
||||
esac
|
||||
{% endraw %}
|
||||
135
Migration/Ansible/roles/samba4-dc/templates/samba-restore.sh.j2
Normal file
135
Migration/Ansible/roles/samba4-dc/templates/samba-restore.sh.j2
Normal file
@@ -0,0 +1,135 @@
|
||||
#!/bin/bash
|
||||
# Samba4 Simple Restore Script
|
||||
# Generated by Ansible
|
||||
|
||||
BASE_BACKUP_DIR="{{ backup_dir | default('/backup/samba') }}"
|
||||
HOSTNAME="{{ target_hostname }}"
|
||||
SAMBA_DIR="/var/lib/samba"
|
||||
ETC_DIR="/etc/samba"
|
||||
|
||||
{% raw %}
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
CYAN='\033[0;36m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo -e "${CYAN}🔄 Samba4 Restore Script"
|
||||
echo "==============================${NC}"
|
||||
|
||||
# Check if backup directory exists
|
||||
if [ ! -d "$BASE_BACKUP_DIR" ]; then
|
||||
echo -e "${RED}❌ Backup directory not found: $BASE_BACKUP_DIR${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# List available backups
|
||||
echo -e "${YELLOW}📁 Available backups for ${HOSTNAME}:${NC}"
|
||||
echo ""
|
||||
|
||||
backup_files=($(ls -1t "$BASE_BACKUP_DIR"/${HOSTNAME}*.tgz 2>/dev/null))
|
||||
|
||||
if [ ${#backup_files[@]} -eq 0 ]; then
|
||||
echo -e "${RED}❌ No backup files found for ${HOSTNAME}${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Display backup files with index and timestamp
|
||||
for i in "${!backup_files[@]}"; do
|
||||
file="${backup_files[$i]}"
|
||||
filename=$(basename "$file")
|
||||
filesize=$(du -h "$file" | cut -f1)
|
||||
timestamp=$(stat -c %y "$file" | cut -d'.' -f1)
|
||||
|
||||
echo -e "${GREEN}[$((i+1))]${NC} $filename"
|
||||
echo " 📅 Created: $timestamp"
|
||||
echo " 📦 Size: $filesize"
|
||||
echo ""
|
||||
done
|
||||
|
||||
# Ask user which backup to restore
|
||||
echo -n -e "${YELLOW}Select backup to restore [1-${#backup_files[@]}]: ${NC}"
|
||||
read -r selection
|
||||
|
||||
# Validate selection
|
||||
if ! [[ "$selection" =~ ^[0-9]+$ ]] || [ "$selection" -lt 1 ] || [ "$selection" -gt ${#backup_files[@]} ]; then
|
||||
echo -e "${RED}❌ Invalid selection${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
selected_backup="${backup_files[$((selection-1))]}"
|
||||
echo -e "${GREEN}✅ Selected: $(basename "$selected_backup")${NC}"
|
||||
echo ""
|
||||
|
||||
# Ask for restore location
|
||||
echo -e "${YELLOW}Restore options:${NC}"
|
||||
echo "1) In place (replace current Samba installation)"
|
||||
echo "2) To custom directory"
|
||||
echo ""
|
||||
echo -n -e "${YELLOW}Choose option [1-2]: ${NC}"
|
||||
read -r restore_option
|
||||
|
||||
case "$restore_option" in
|
||||
1)
|
||||
# In-place restore
|
||||
echo -e "${YELLOW}⚠️ WARNING: This will replace your current Samba installation!${NC}"
|
||||
echo -n -e "${RED}Are you sure? Type 'YES' to continue: ${NC}"
|
||||
read -r confirmation
|
||||
|
||||
if [ "$confirmation" != "YES" ]; then
|
||||
echo -e "${YELLOW}🚫 Restore cancelled${NC}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo -e "${CYAN}🛑 Stopping Samba service...${NC}"
|
||||
systemctl stop samba-ad-dc
|
||||
|
||||
echo -e "${CYAN}📦 Restoring backup directly to filesystem...${NC}"
|
||||
tar -xzf "$selected_backup" -C /
|
||||
|
||||
echo -e "${GREEN}✅ Samba directories restored${NC}"
|
||||
|
||||
echo -e "${CYAN}🚀 Starting Samba service...${NC}"
|
||||
systemctl start samba-ad-dc
|
||||
|
||||
# Check service status
|
||||
sleep 3
|
||||
if systemctl is-active --quiet samba-ad-dc; then
|
||||
echo -e "${GREEN}✅ Samba restore completed successfully!${NC}"
|
||||
echo -e "${GREEN}✅ Samba service is running${NC}"
|
||||
else
|
||||
echo -e "${RED}❌ Samba service failed to start${NC}"
|
||||
echo "Check logs: journalctl -u samba-ad-dc"
|
||||
fi
|
||||
;;
|
||||
|
||||
2)
|
||||
# Custom directory restore
|
||||
echo -n -e "${YELLOW}Enter target directory: ${NC}"
|
||||
read -r target_dir
|
||||
|
||||
if [ -z "$target_dir" ]; then
|
||||
echo -e "${RED}❌ Target directory cannot be empty${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$target_dir"
|
||||
|
||||
echo -e "${CYAN}📦 Extracting backup to $target_dir...${NC}"
|
||||
tar -xzf "$selected_backup" -C "$target_dir"
|
||||
|
||||
echo -e "${GREEN}✅ Backup extracted to: $target_dir${NC}"
|
||||
echo -e "${CYAN}📁 Contents:${NC}"
|
||||
ls -la "$target_dir"
|
||||
;;
|
||||
|
||||
*)
|
||||
echo -e "${RED}❌ Invalid option${NC}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}🎉 Restore operation completed!${NC}"
|
||||
{% endraw %}
|
||||
35
Migration/Ansible/roles/system/tasks/bash_config.yml
Normal file
35
Migration/Ansible/roles/system/tasks/bash_config.yml
Normal file
@@ -0,0 +1,35 @@
|
||||
---
|
||||
# Bash Configuration Tasks
|
||||
- name: Configure bash prompt for installer user
|
||||
lineinfile:
|
||||
path: /home/installer/.bashrc
|
||||
regexp: '^PS1='
|
||||
line: 'PS1="\033[0;32m[\u@\h]\w\033[m: $ "'
|
||||
create: yes
|
||||
owner: installer
|
||||
group: installer
|
||||
mode: '0644'
|
||||
backup: yes
|
||||
|
||||
- name: Configure bash prompt for root user
|
||||
lineinfile:
|
||||
path: /root/.bashrc
|
||||
regexp: '^PS1='
|
||||
line: 'PS1="\033[0;31m[\u@\h]\w\033[m: # "'
|
||||
create: yes
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
backup: yes
|
||||
|
||||
- name: Configure default bash prompt in /etc/skel for new users
|
||||
lineinfile:
|
||||
path: /etc/skel/.bashrc
|
||||
regexp: '^PS1='
|
||||
line: 'PS1="\033[0;32m[\u@\h]\w\033[m: $ "'
|
||||
create: yes
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
backup: yes
|
||||
|
||||
63
Migration/Ansible/roles/system/tasks/hostname.yml
Normal file
63
Migration/Ansible/roles/system/tasks/hostname.yml
Normal file
@@ -0,0 +1,63 @@
|
||||
---
|
||||
# Hostname configuration tasks
|
||||
- name: Get current hostname
|
||||
command: hostname
|
||||
register: current_hostname_result
|
||||
changed_when: false
|
||||
|
||||
- name: Validate target hostname is properly configured
|
||||
fail:
|
||||
msg: |
|
||||
ERROR: target_hostname is not properly configured!
|
||||
|
||||
Current hostname: {{ current_hostname_result.stdout }}
|
||||
Target hostname: {{ target_hostname | default('NOT SET') }}
|
||||
|
||||
Please update your inventory.yml file with the correct target_hostname.
|
||||
Example:
|
||||
all:
|
||||
hosts:
|
||||
your-server:
|
||||
ansible_host: your_server_ip
|
||||
target_hostname: your-desired-hostname
|
||||
samba_realm: your.domain.local
|
||||
|
||||
The target_hostname must be set in inventory for Samba4 domain controller installation.
|
||||
when:
|
||||
- target_hostname is not defined or target_hostname == ""
|
||||
|
||||
- name: Display hostname validation status
|
||||
debug:
|
||||
msg: |
|
||||
✅ Hostname validation passed:
|
||||
Current: {{ current_hostname_result.stdout }}
|
||||
Target: {{ target_hostname }}
|
||||
Domain: {{ samba_realm }}
|
||||
|
||||
{% if current_hostname_result.stdout == target_hostname %}
|
||||
✅ Hostname is already correctly set - no change needed.
|
||||
{% else %}
|
||||
⚠️ Hostname will be changed from {{ current_hostname_result.stdout }} to {{ target_hostname }}
|
||||
{% endif %}
|
||||
|
||||
- name: Update /etc/hosts with new hostname
|
||||
lineinfile:
|
||||
path: /etc/hosts
|
||||
regexp: '^127\.0\.1\.1\s+.*'
|
||||
line: "127.0.1.1 {{ target_hostname }}.{{ samba_realm }} {{ target_hostname }}"
|
||||
state: present
|
||||
|
||||
- name: Get current server IP address
|
||||
shell: |
|
||||
# Get the IP of the default route interface
|
||||
ip route get 8.8.8.8 | grep -oP 'src \K\S+' | head -1
|
||||
register: current_server_ip
|
||||
changed_when: false
|
||||
|
||||
- name: Add domain entry to /etc/hosts
|
||||
lineinfile:
|
||||
path: /etc/hosts
|
||||
regexp: "^{{ current_server_ip.stdout }}\\s+.*"
|
||||
line: "{{ current_server_ip.stdout }} {{ target_hostname }}.{{ samba_realm }} {{ target_hostname }}"
|
||||
state: present
|
||||
|
||||
83
Migration/Ansible/roles/system/tasks/main.yml
Normal file
83
Migration/Ansible/roles/system/tasks/main.yml
Normal file
@@ -0,0 +1,83 @@
|
||||
---
|
||||
# System Role - Main Tasks (Simplified for compatibility)
|
||||
|
||||
- name: Check if server has static IP configuration
|
||||
block:
|
||||
- name: Get network interface configuration
|
||||
shell: |
|
||||
# Check for static IP in netplan configuration
|
||||
if [ -d /etc/netplan ]; then
|
||||
grep -r "dhcp4.*false\|addresses:" /etc/netplan/ 2>/dev/null && echo "static_found" || echo "no_static"
|
||||
# Check for static IP in network interfaces (older systems)
|
||||
elif [ -f /etc/network/interfaces ]; then
|
||||
grep -E "^iface.*static" /etc/network/interfaces 2>/dev/null && echo "static_found" || echo "no_static"
|
||||
# Check for static IP in NetworkManager
|
||||
elif [ -d /etc/NetworkManager/system-connections ]; then
|
||||
grep -r "method=manual\|method=static" /etc/NetworkManager/system-connections/ 2>/dev/null && echo "static_found" || echo "no_static"
|
||||
else
|
||||
echo "no_config_found"
|
||||
fi
|
||||
register: static_ip_check
|
||||
changed_when: false
|
||||
|
||||
- name: Verify static IP configuration exists
|
||||
fail:
|
||||
msg: |
|
||||
ERROR: No static IP configuration detected!
|
||||
|
||||
A Samba4 Domain Controller requires a static IP address.
|
||||
Please configure a static IP before proceeding.
|
||||
|
||||
Current network configuration method appears to be DHCP.
|
||||
|
||||
To configure static IP:
|
||||
- For netplan: Edit /etc/netplan/*.yaml files
|
||||
- For interfaces: Edit /etc/network/interfaces
|
||||
- For NetworkManager: Use nmcli or edit connection files
|
||||
when: static_ip_check.stdout == "no_static" or static_ip_check.stdout == "no_config_found"
|
||||
|
||||
- name: Display static IP confirmation
|
||||
debug:
|
||||
msg: "✓ Static IP configuration detected - proceeding with installation"
|
||||
when: static_ip_check.stdout == "static_found"
|
||||
|
||||
- name: Update package cache
|
||||
apt:
|
||||
update_cache: yes
|
||||
cache_valid_time: 3600
|
||||
|
||||
- name: Install base system packages
|
||||
apt:
|
||||
name:
|
||||
- curl
|
||||
- wget
|
||||
- vim
|
||||
- htop
|
||||
- tree
|
||||
- unzip
|
||||
- software-properties-common
|
||||
- apt-transport-https
|
||||
- ca-certificates
|
||||
- gnupg
|
||||
- lsb-release
|
||||
- rsyslog
|
||||
- mc
|
||||
- sudo
|
||||
- nfs-common
|
||||
state: present
|
||||
|
||||
- name: Cloud init is not wanted on DCs - remove if present
|
||||
apt:
|
||||
name:
|
||||
- cloudinit
|
||||
state: absent
|
||||
|
||||
- name: Configure timezone
|
||||
timezone:
|
||||
name: Europe/Paris
|
||||
|
||||
- name: Include bash configuration tasks
|
||||
include_tasks: bash_config.yml
|
||||
|
||||
- name: Validate hostname configuration
|
||||
include_tasks: hostname.yml
|
||||
164
Migration/DOCUMENTATION_ImportDns.md
Normal file
164
Migration/DOCUMENTATION_ImportDns.md
Normal file
@@ -0,0 +1,164 @@
|
||||
# Documentation - Script importDns.sh
|
||||
|
||||
## Vue d'ensemble
|
||||
|
||||
Le script `importDns.sh` est la nouvelle version améliorée pour importer les zones et enregistrements DNS depuis les fichiers CSV vers Samba4. Il remplace l'ancien script généré automatiquement par une approche plus flexible et maintenable.
|
||||
|
||||
## Fonctionnalités
|
||||
|
||||
### ✅ Import basé sur CSV
|
||||
- Utilise les fichiers CSV générés par `exportDns.ps1`
|
||||
- Lecture du fichier `Transfert/Dns/dns_zones.csv` pour la liste des zones
|
||||
- Traitement automatique des fichiers `dns_records_<zone>.csv` correspondants
|
||||
|
||||
### ✅ Interface utilisateur améliorée
|
||||
- **Affichage coloré** avec codes de couleur pour les différents types de messages
|
||||
- **Demande interactive** des credentials Samba4
|
||||
- **Mode dry-run** pour tester avant l'import réel
|
||||
- **Progression détaillée** avec compteurs de réussite/échec
|
||||
|
||||
### ✅ Gestion robuste des erreurs
|
||||
- **Vérifications préalables** des prérequis
|
||||
- **Validation des credentials** avant de commencer
|
||||
- **Création automatique des zones** si elles n'existent pas
|
||||
- **Continuation** même en cas d'erreurs sur des enregistrements individuels
|
||||
|
||||
### ✅ Filtrage intelligent
|
||||
- **Ignore les zones reverse** (in-addr.arpa)
|
||||
- **Traite seulement les zones Primary Forward**
|
||||
- **Exclut les enregistrements système** (@, SOA, NS, _service)
|
||||
|
||||
## Utilisation
|
||||
|
||||
### Prérequis
|
||||
1. Avoir exécuté `exportDns.ps1` sur Windows pour générer les fichiers CSV
|
||||
2. Avoir transféré le dossier `Transfert/Dns/` sur le serveur Samba4
|
||||
3. Samba4 doit être installé et configuré
|
||||
|
||||
### Exécution
|
||||
```bash
|
||||
# Se placer dans le répertoire de migration
|
||||
cd /data/apps/Migration
|
||||
|
||||
# Exécuter le script
|
||||
./importDns.sh
|
||||
```
|
||||
|
||||
### Interface interactive
|
||||
|
||||
1. **Vérification des prérequis** : Le script vérifie automatiquement la présence de `samba-tool` et des fichiers CSV
|
||||
|
||||
2. **Credentials** :
|
||||
- Nom d'utilisateur (défaut: Administrator)
|
||||
- Mot de passe (saisie masquée)
|
||||
- Validation automatique des credentials
|
||||
|
||||
3. **Mode d'exécution** :
|
||||
- **Option 1** : Dry-run (affiche les commandes sans les exécuter)
|
||||
- **Option 2** : Import réel
|
||||
|
||||
4. **Traitement** :
|
||||
- Création automatique des zones DNS
|
||||
- Import des enregistrements avec feedback détaillé
|
||||
- Statistiques finales
|
||||
|
||||
## Structure des fichiers CSV attendus
|
||||
|
||||
### dns_zones.csv
|
||||
```csv
|
||||
"ZoneName","ZoneType","IsReverse","IsPrimary","DynamicUpdate","RecordCount"
|
||||
"example.com","Forward","False","True","Secure","25"
|
||||
```
|
||||
|
||||
### dns_records_<zone>.csv
|
||||
```csv
|
||||
"Name","Type","TTL","Value","Timestamp"
|
||||
"www","A","3600","192.168.1.100","Static"
|
||||
"mail","CNAME","3600","www.example.com.","Static"
|
||||
```
|
||||
|
||||
## Avantages par rapport à l'ancien script
|
||||
|
||||
| Aspect | Ancien script | Nouveau script |
|
||||
|--------|---------------|----------------|
|
||||
| **Source des données** | Hardcodé dans le script | Fichiers CSV flexibles |
|
||||
| **Maintenance** | Modification du code | Modification des CSV |
|
||||
| **Credentials** | Hardcodés ou répétés | Demande interactive |
|
||||
| **Mode test** | Non disponible | Mode dry-run intégré |
|
||||
| **Gestion d'erreurs** | Basique | Robuste avec continuation |
|
||||
| **Interface** | Texte simple | Interface colorée et claire |
|
||||
| **Création de zones** | Manuelle | Automatique avec vérification |
|
||||
| **Filtrage** | Limité | Intelligent (types de zones/enregistrements) |
|
||||
|
||||
## Messages et codes de retour
|
||||
|
||||
### Codes couleur
|
||||
- 🔵 **[INFO]** : Messages informatifs (bleu)
|
||||
- 🟢 **[OK]** : Opérations réussies (vert)
|
||||
- 🟡 **[WARNING]** : Avertissements (jaune)
|
||||
- 🔴 **[ERREUR]** : Erreurs (rouge)
|
||||
|
||||
### Codes de sortie
|
||||
- **0** : Succès complet
|
||||
- **1** : Erreur de prérequis ou credentials invalides
|
||||
|
||||
## Dépannage
|
||||
|
||||
### "samba-tool non trouvé"
|
||||
- Vérifier que Samba4 est installé : `which samba-tool`
|
||||
- Installer Samba4 si nécessaire
|
||||
|
||||
### "Répertoire DNS non trouvé"
|
||||
- Vérifier que le dossier `Transfert/Dns/` existe
|
||||
- Transférer les fichiers depuis Windows si nécessaire
|
||||
|
||||
### "Credentials invalides"
|
||||
- Vérifier le nom d'utilisateur et mot de passe
|
||||
- S'assurer que l'utilisateur a les droits administrateur Samba4
|
||||
|
||||
### "Impossible de créer la zone"
|
||||
- Vérifier les droits de l'utilisateur
|
||||
- Contrôler les logs Samba : `journalctl -u samba-ad-dc`
|
||||
|
||||
## Exemple d'exécution
|
||||
|
||||
```bash
|
||||
$ ./importDns.sh
|
||||
==================================================================================
|
||||
IMPORT DNS VERS SAMBA4
|
||||
==================================================================================
|
||||
|
||||
[INFO] Vérification des prérequis...
|
||||
[OK] Prérequis validés
|
||||
[INFO] Configuration des credentials Samba4
|
||||
|
||||
Nom d'utilisateur administrateur Samba [Administrator]:
|
||||
Mot de passe pour Administrator:
|
||||
|
||||
[INFO] Test des credentials...
|
||||
[OK] Credentials validés pour Administrator
|
||||
|
||||
Modes d'exécution disponibles:
|
||||
1. Dry-run (afficher les commandes sans les exécuter)
|
||||
2. Import réel (exécuter les commandes)
|
||||
|
||||
Choisissez le mode [1/2]: 2
|
||||
[INFO] Mode import réel activé
|
||||
|
||||
[INFO] Début de l'import DNS depuis les fichiers CSV
|
||||
|
||||
===================================================================================
|
||||
[INFO] Traitement de la zone: example.com
|
||||
|
||||
[INFO] Création de la zone: example.com
|
||||
[OK] Zone example.com créée avec succès
|
||||
[INFO] Traitement des enregistrements pour la zone: example.com
|
||||
[OK] Ajout enregistrement: www (A) → 192.168.1.100
|
||||
[OK] Ajout enregistrement: mail (CNAME) → www.example.com.
|
||||
[INFO] Zone example.com: 2/2 enregistrements traités avec succès
|
||||
|
||||
===================================================================================
|
||||
[OK] Import terminé: 1/1 zones traitées
|
||||
|
||||
[OK] Script d'import DNS terminé avec succès !
|
||||
```
|
||||
1460
Migration/README.md
Normal file
1460
Migration/README.md
Normal file
File diff suppressed because it is too large
Load Diff
81
Migration/TOC.md
Normal file
81
Migration/TOC.md
Normal file
@@ -0,0 +1,81 @@
|
||||
# Table des Matières - Migration Active Directory vers Samba4
|
||||
|
||||
## Structure du document
|
||||
|
||||
**1 Migration Active Directory vers Samba4**
|
||||
1.1 Introduction
|
||||
1.2 Rappels techniques
|
||||
1.2.1 Identifiant de domaine (ObjectSid)
|
||||
1.2.2 Utilisateurs et objets
|
||||
1.2.3 Relations d'approbation et comptes machine
|
||||
|
||||
**2 Procédure de migration**
|
||||
2.1 Pré-requis
|
||||
2.1.1 Droits et accès nécessaires
|
||||
2.1.2 Outils requis
|
||||
2.2 Préparation de l'environnement cible
|
||||
2.2.1 Création de la machine virtuelle
|
||||
2.2.2 Installation de Debian
|
||||
2.2.3 Installer Debian depuis template
|
||||
2.2.4 Configuration de l'accès SSH depuis le bastion
|
||||
2.3 Export des données Active Directory
|
||||
2.3.1 Pré-requis pour l'export
|
||||
2.3.2 Procédure d'export
|
||||
2.3.3 Transfert des données vers le serveur Linux Samba
|
||||
2.4 Installation et configuration de Samba4
|
||||
2.4.1 Préparation des variables Ansible
|
||||
2.4.2 Exécution de l'installation
|
||||
2.4.3 Arrêt serveur Samba
|
||||
2.4.4 Création des comptes utilisateurs
|
||||
2.4.5 Création des groupes
|
||||
2.4.6 Création des comptes d'ordinateurs
|
||||
2.4.7 Changement du Rid
|
||||
2.4.8 Reconnecter les apps
|
||||
2.5 Migration des postes de travail
|
||||
2.5.1 Préparation des postes avant migration
|
||||
2.5.2 Réinitialisation compte d'ordinateur
|
||||
2.5.3 Réinitialisation mot de passe utilisateur
|
||||
|
||||
**3 Migration DNS**
|
||||
3.1 Export DNS
|
||||
3.1.1 Fichiers générés
|
||||
3.1.2 Transfert des fichiers
|
||||
3.2 Import DNS
|
||||
|
||||
**4 Poste de test**
|
||||
4.1 RSAT
|
||||
|
||||
**5 Dépannage et résolution de problèmes**
|
||||
5.1 Problèmes courants
|
||||
5.1.1 Sauvegarde et restauration d'urgence
|
||||
5.2 Checklist de validation finale
|
||||
5.2.1 Avant la bascule en production
|
||||
5.2.2 Après la bascule
|
||||
|
||||
---
|
||||
|
||||
## Statistiques du document
|
||||
|
||||
- **Chapitres principaux :** 5
|
||||
- **Sections de niveau 2 :** 12
|
||||
- **Sections de niveau 3 :** 23
|
||||
- **Total des sections :** 40
|
||||
|
||||
## Structure logique
|
||||
|
||||
### Phase 1 : Préparation (Chapitre 1-2.2)
|
||||
- Compréhension des concepts AD
|
||||
- Préparation de l'infrastructure
|
||||
|
||||
### Phase 2 : Export et Installation (Chapitre 2.3-2.4)
|
||||
- Export des données Windows AD
|
||||
- Installation et configuration Samba4
|
||||
- Import des objets (utilisateurs, groupes, ordinateurs)
|
||||
|
||||
### Phase 3 : Migration avancée (Chapitre 2.5-3)
|
||||
- Migration des postes de travail
|
||||
- Migration DNS complète
|
||||
|
||||
### Phase 4 : Test et Support (Chapitre 4-5)
|
||||
- Configuration du poste de test
|
||||
- Procédures de dépannage et validation
|
||||
1779
Migration/Transfert/Dns/dns_export_complete.json
Normal file
1779
Migration/Transfert/Dns/dns_export_complete.json
Normal file
File diff suppressed because it is too large
Load Diff
2
Migration/Transfert/users.sample
Normal file
2
Migration/Transfert/users.sample
Normal file
@@ -0,0 +1,2 @@
|
||||
UGIVEN,LOGIN,OBJECTSID,UNAME
|
||||
Serge,admin-sn,S-1-5-21-xxxxxxx-xxxxxxxxxx-xxxxxxxxx,NOEL admin
|
||||
23
Migration/computer.ldif.orig
Normal file
23
Migration/computer.ldif.orig
Normal file
@@ -0,0 +1,23 @@
|
||||
dn: CN=NAME,CN=Computers,DC=aipice,DC=local
|
||||
objectClass: top
|
||||
objectClass: person
|
||||
objectClass: organizationalPerson
|
||||
objectClass: user
|
||||
objectClass: computer
|
||||
cn: NAME
|
||||
instanceType: 4
|
||||
name: NAME
|
||||
userAccountControl: 4096
|
||||
badPwdCount: 0
|
||||
codePage: 0
|
||||
countryCode: 0
|
||||
badPasswordTime: 0
|
||||
lastLogoff: 0
|
||||
lastLogon: 0
|
||||
pwdLastSet: 0
|
||||
objectSid: OBJECTSID
|
||||
accountExpires: 9223372036854775807
|
||||
logonCount: 0
|
||||
sAMAccountName: NAME$
|
||||
objectCategory: CN=Computer,CN=Schema,CN=Configuration,DC=aipice,DC=local
|
||||
distinguishedName: CN=NAME,CN=Computers,DC=aipice,DC=local
|
||||
139
Migration/create_samba_computers.sh
Executable file
139
Migration/create_samba_computers.sh
Executable file
@@ -0,0 +1,139 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script to create Samba4 computer accounts from CSV file using ldbmodify
|
||||
# Usage: ./create_samba_computers.sh
|
||||
|
||||
# Set script directory for relative paths
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
CSV_FILE="$SCRIPT_DIR/Transfert/computers.csv"
|
||||
TEMPLATE_FILE="$SCRIPT_DIR/computer.ldif.orig"
|
||||
TEMP_LDIF="$SCRIPT_DIR/computer.ldif"
|
||||
|
||||
# Check if running as root
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "Error: This script must be run as root to access Samba's LDB database."
|
||||
echo "Please run with: sudo $0"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if required files exist
|
||||
if [[ ! -f "$CSV_FILE" ]]; then
|
||||
echo "Error: CSV file not found at $CSV_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -f "$TEMPLATE_FILE" ]]; then
|
||||
echo "Error: Template file not found at $TEMPLATE_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if ldbmodify is available
|
||||
if ! command -v ldbmodify &> /dev/null; then
|
||||
echo "Error: ldbmodify command not found. Please ensure Samba4 is installed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Function to clean up temp file
|
||||
cleanup() {
|
||||
if [[ -f "$TEMP_LDIF" ]]; then
|
||||
rm -f "$TEMP_LDIF"
|
||||
echo "Cleaned up temporary file: $TEMP_LDIF"
|
||||
fi
|
||||
}
|
||||
|
||||
# Set trap to cleanup on exit
|
||||
trap cleanup EXIT
|
||||
|
||||
echo "Starting Samba4 computer account creation process..."
|
||||
echo "Reading computers from: $CSV_FILE"
|
||||
echo "Using template: $TEMPLATE_FILE"
|
||||
echo ""
|
||||
|
||||
# Counter for statistics
|
||||
total_computers=0
|
||||
successful_computers=0
|
||||
failed_computers=0
|
||||
|
||||
# Read CSV file line by line (skip header)
|
||||
while IFS=',' read -r NAME OBJECTSID; do
|
||||
# Skip header line
|
||||
if [[ "$NAME" == "NAME" && "$OBJECTSID" == "OBJECTSID" ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
total_computers=$((total_computers + 1))
|
||||
|
||||
# Trim whitespace and newlines from variables
|
||||
NAME=$(echo "$NAME" | tr -d '\r\n' | xargs)
|
||||
OBJECTSID=$(echo "$OBJECTSID" | tr -d '\r\n' | xargs)
|
||||
|
||||
echo "Processing computer $total_computers: $NAME"
|
||||
|
||||
# Check if any required field is empty
|
||||
if [[ -z "$NAME" || -z "$OBJECTSID" ]]; then
|
||||
echo " Warning: Skipping computer due to missing data (NAME='$NAME', OBJECTSID='$OBJECTSID')"
|
||||
failed_computers=$((failed_computers + 1))
|
||||
continue
|
||||
fi
|
||||
|
||||
# Validate ObjectSID format
|
||||
if [[ ! "$OBJECTSID" =~ ^S-1-5-21- ]]; then
|
||||
echo " Warning: Skipping computer due to invalid ObjectSID format: $OBJECTSID"
|
||||
failed_computers=$((failed_computers + 1))
|
||||
continue
|
||||
fi
|
||||
|
||||
# Create computer.ldif from template by replacing placeholders
|
||||
if ! cp "$TEMPLATE_FILE" "$TEMP_LDIF" 2>/dev/null; then
|
||||
echo " ✗ Failed to copy template file"
|
||||
failed_computers=$((failed_computers + 1))
|
||||
continue
|
||||
fi
|
||||
|
||||
# Use sed to replace placeholders (handle special characters properly)
|
||||
sed -i "s|NAME|$NAME|g" "$TEMP_LDIF"
|
||||
sed -i "s|OBJECTSID|$OBJECTSID|g" "$TEMP_LDIF"
|
||||
|
||||
echo " Created LDIF file for computer: $NAME"
|
||||
|
||||
# Execute ldbmodify command
|
||||
if ldbmodify -H /var/lib/samba/private/sam.ldb --controls="local_oid:1.3.6.1.4.1.7165.4.3.12:0" "$TEMP_LDIF" 2>/dev/null; then
|
||||
echo " ✓ Successfully created computer account: $NAME"
|
||||
successful_computers=$((successful_computers + 1))
|
||||
else
|
||||
echo " ✗ Failed to create computer account: $NAME"
|
||||
echo " Computer may already exist or check Samba permissions."
|
||||
failed_computers=$((failed_computers + 1))
|
||||
fi
|
||||
|
||||
echo ""
|
||||
done < "$CSV_FILE"
|
||||
|
||||
# Display final statistics
|
||||
echo "========================================="
|
||||
echo "Computer account creation process completed!"
|
||||
echo "Total computers processed: $total_computers"
|
||||
echo "Successfully created: $successful_computers"
|
||||
echo "Failed: $failed_computers"
|
||||
echo "========================================="
|
||||
|
||||
# Note about permissions and next steps
|
||||
if [[ $failed_computers -gt 0 ]]; then
|
||||
echo ""
|
||||
echo "Note: If computer accounts failed to be created, possible causes:"
|
||||
echo "1. Computer account already exists in the domain"
|
||||
echo "2. ObjectSID conflict or duplication"
|
||||
echo "3. Samba4 service not running: sudo systemctl status samba-ad-dc"
|
||||
fi
|
||||
|
||||
if [[ $successful_computers -gt 0 ]]; then
|
||||
echo ""
|
||||
echo "✅ Computer accounts created successfully!"
|
||||
echo "Next steps for each workstation:"
|
||||
echo "1. On each computer, open PowerShell as Administrator"
|
||||
echo "2. Run: Reset-ComputerMachinePassword -Credential <AdminAccount> -Server <DC_IP>"
|
||||
echo "3. Reboot the computer to complete the domain rejoin process"
|
||||
echo ""
|
||||
echo "To verify created computer accounts:"
|
||||
echo "samba-tool computer list"
|
||||
fi
|
||||
178
Migration/create_samba_groups.sh
Executable file
178
Migration/create_samba_groups.sh
Executable file
@@ -0,0 +1,178 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script to create Samba4 groups from CSV file using ldbmodify
|
||||
# Usage: ./create_samba_groups.sh
|
||||
|
||||
# Set script directory for relative paths
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
CSV_FILE="$SCRIPT_DIR/Transfert/groups.csv"
|
||||
TEMPLATE_FILE="$SCRIPT_DIR/group.ldif.orig"
|
||||
TEMP_LDIF="$SCRIPT_DIR/group.ldif"
|
||||
|
||||
# Check if running as root
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "Error: This script must be run as root to access Samba's LDB database."
|
||||
echo "Please run with: sudo $0"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if required files exist
|
||||
if [[ ! -f "$CSV_FILE" ]]; then
|
||||
echo "Error: CSV file not found at $CSV_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -f "$TEMPLATE_FILE" ]]; then
|
||||
echo "Error: Template file not found at $TEMPLATE_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if ldbmodify is available
|
||||
if ! command -v ldbmodify &> /dev/null; then
|
||||
echo "Error: ldbmodify command not found. Please ensure Samba4 is installed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Function to clean up temp file
|
||||
cleanup() {
|
||||
if [[ -f "$TEMP_LDIF" ]]; then
|
||||
rm -f "$TEMP_LDIF"
|
||||
echo "Cleaned up temporary file: $TEMP_LDIF"
|
||||
fi
|
||||
}
|
||||
|
||||
# Set trap to cleanup on exit
|
||||
trap cleanup EXIT
|
||||
|
||||
# Function to sanitize input (escape special characters for sed)
|
||||
sanitize_for_sed() {
|
||||
local input="$1"
|
||||
# Escape special sed characters: / \ &
|
||||
echo "$input" | sed 's/[\/&\\]/\\&/g'
|
||||
}
|
||||
|
||||
# Function to validate group data
|
||||
validate_group_data() {
|
||||
local name="$1"
|
||||
local objectsid="$2"
|
||||
|
||||
# Check for empty fields
|
||||
if [[ -z "$name" || -z "$objectsid" ]]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check ObjectSID format (should start with S-1-5-21)
|
||||
if [[ ! "$objectsid" =~ ^S-1-5-21- ]]; then
|
||||
return 2
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
echo "Starting Samba4 group creation process..."
|
||||
echo "Reading groups from: $CSV_FILE"
|
||||
echo "Using template: $TEMPLATE_FILE"
|
||||
echo ""
|
||||
|
||||
# Counter for statistics
|
||||
total_groups=0
|
||||
successful_groups=0
|
||||
failed_groups=0
|
||||
skipped_groups=0
|
||||
|
||||
# Read CSV file line by line (skip header)
|
||||
while IFS=',' read -r NAME OBJECTSID; do
|
||||
# Skip header line
|
||||
if [[ "$NAME" == "NAME" && "$OBJECTSID" == "OBJECTSID" ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
total_groups=$((total_groups + 1))
|
||||
|
||||
# Trim whitespace and newlines from variables
|
||||
NAME=$(echo "$NAME" | tr -d '\r\n' | xargs)
|
||||
OBJECTSID=$(echo "$OBJECTSID" | tr -d '\r\n' | xargs)
|
||||
|
||||
echo "Processing group $total_groups: $NAME"
|
||||
|
||||
# Validate group data
|
||||
validate_group_data "$NAME" "$OBJECTSID"
|
||||
validation_result=$?
|
||||
|
||||
case $validation_result in
|
||||
1)
|
||||
echo " Warning: Skipping group due to missing data (NAME='$NAME', OBJECTSID='$OBJECTSID')"
|
||||
skipped_groups=$((skipped_groups + 1))
|
||||
continue
|
||||
;;
|
||||
2)
|
||||
echo " Warning: Skipping group due to invalid ObjectSID format: $OBJECTSID"
|
||||
skipped_groups=$((skipped_groups + 1))
|
||||
continue
|
||||
;;
|
||||
3)
|
||||
echo " Warning: Skipping group due to invalid name format (contains LDAP special characters): '$NAME'"
|
||||
skipped_groups=$((skipped_groups + 1))
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
|
||||
# Create group.ldif from template by replacing placeholders
|
||||
if ! cp "$TEMPLATE_FILE" "$TEMP_LDIF" 2>/dev/null; then
|
||||
echo " ✗ Failed to copy template file"
|
||||
failed_groups=$((failed_groups + 1))
|
||||
continue
|
||||
fi
|
||||
|
||||
# Sanitize inputs for sed
|
||||
NAME_SAFE=$(sanitize_for_sed "$NAME")
|
||||
OBJECTSID_SAFE=$(sanitize_for_sed "$OBJECTSID")
|
||||
|
||||
# Use sed to replace placeholders with safe inputs
|
||||
sed -i "s/NAME/$NAME_SAFE/g" "$TEMP_LDIF"
|
||||
sed -i "s/OBJECTSID/$OBJECTSID_SAFE/g" "$TEMP_LDIF"
|
||||
|
||||
echo " Created LDIF file for group: $NAME"
|
||||
|
||||
# Execute ldbmodify command
|
||||
if ldbmodify -H /var/lib/samba/private/sam.ldb --controls="local_oid:1.3.6.1.4.1.7165.4.3.12:0" "$TEMP_LDIF" 2>/dev/null; then
|
||||
echo " ✓ Successfully created group: $NAME"
|
||||
successful_groups=$((successful_groups + 1))
|
||||
else
|
||||
echo " ✗ Failed to create group: $NAME"
|
||||
echo " Group may already exist or check Samba permissions."
|
||||
failed_groups=$((failed_groups + 1))
|
||||
|
||||
# Try to get more specific error information
|
||||
echo " Attempting to get detailed error..."
|
||||
ldbmodify -H /var/lib/samba/private/sam.ldb --controls="local_oid:1.3.6.1.4.1.7165.4.3.12:0" "$TEMP_LDIF" 2>&1 | head -3 | sed 's/^/ /'
|
||||
fi
|
||||
|
||||
echo ""
|
||||
done < "$CSV_FILE"
|
||||
|
||||
# Display final statistics
|
||||
echo "========================================="
|
||||
echo "Group creation process completed!"
|
||||
echo "Total groups processed: $total_groups"
|
||||
echo "Successfully created: $successful_groups"
|
||||
echo "Failed: $failed_groups"
|
||||
echo "Skipped (validation errors): $skipped_groups"
|
||||
echo "========================================="
|
||||
|
||||
# Provide recommendations
|
||||
if [[ $failed_groups -gt 0 ]]; then
|
||||
echo ""
|
||||
echo "Note: If groups failed to be created, possible causes:"
|
||||
echo "1. Group already exists in the domain"
|
||||
echo "2. ObjectSID conflict or duplication"
|
||||
echo "3. Invalid characters in group name"
|
||||
echo "4. Insufficient permissions (already running as root)"
|
||||
echo "5. Samba4 service not running: sudo systemctl status samba-ad-dc"
|
||||
fi
|
||||
|
||||
# Show created groups
|
||||
if [[ $successful_groups -gt 0 ]]; then
|
||||
echo ""
|
||||
echo "To verify created groups, run:"
|
||||
echo "samba-tool group list | grep -E '$(echo "$CSV_FILE" | xargs -I {} awk -F',' 'NR>1 {print $1}' {} | tr '\n' '|' | sed 's/|$//')'"
|
||||
fi
|
||||
114
Migration/create_samba_users.sh
Executable file
114
Migration/create_samba_users.sh
Executable file
@@ -0,0 +1,114 @@
|
||||
#!/bin/bash
|
||||
|
||||
DEFAULT_PASSWORD="Welcome123!"
|
||||
# Script to create Samba4 users from CSV file using ldbmodify
|
||||
# Usage: ./create_samba_users.sh
|
||||
|
||||
# Set script directory for relative paths
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
CSV_FILE="$SCRIPT_DIR/Transfert/users.csv"
|
||||
TEMPLATE_FILE="$SCRIPT_DIR/user.ldif.orig"
|
||||
TEMP_LDIF="$SCRIPT_DIR/user.ldif"
|
||||
|
||||
# Check if running as root
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "Error: This script must be run as root to access Samba's LDB database."
|
||||
echo "Please run with: sudo $0"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if required files exist
|
||||
if [[ ! -f "$CSV_FILE" ]]; then
|
||||
echo "Error: CSV file not found at $CSV_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -f "$TEMPLATE_FILE" ]]; then
|
||||
echo "Error: Template file not found at $TEMPLATE_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if ldbmodify is available
|
||||
if ! command -v ldbmodify &> /dev/null; then
|
||||
echo "Error: ldbmodify command not found. Please ensure Samba4 is installed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Function to clean up temp file
|
||||
cleanup() {
|
||||
if [[ -f "$TEMP_LDIF" ]]; then
|
||||
rm -f "$TEMP_LDIF"
|
||||
echo "Cleaned up temporary file: $TEMP_LDIF"
|
||||
fi
|
||||
}
|
||||
|
||||
# Set trap to cleanup on exit
|
||||
trap cleanup EXIT
|
||||
|
||||
echo "Starting Samba4 user creation process..."
|
||||
echo "Reading users from: $CSV_FILE"
|
||||
echo "Using template: $TEMPLATE_FILE"
|
||||
echo ""
|
||||
|
||||
# Counter for statistics
|
||||
total_users=0
|
||||
successful_users=0
|
||||
failed_users=0
|
||||
|
||||
# Read CSV file line by line (skip header)
|
||||
tail -n +2 "$CSV_FILE" | while IFS=',' read -r UGIVEN LOGIN OBJECTSID UNAME; do
|
||||
total_users=$((total_users + 1))
|
||||
|
||||
# Trim whitespace and newlines from variables
|
||||
UNAME=$(echo "$UNAME" | tr -d '\r\n' | xargs)
|
||||
|
||||
echo "Processing user $total_users: $UGIVEN $UNAME (login: $LOGIN)"
|
||||
|
||||
# Check if any required field is empty
|
||||
if [[ -z "$UGIVEN" || -z "$LOGIN" || -z "$OBJECTSID" || -z "$UNAME" ]]; then
|
||||
echo " Warning: Skipping user due to missing data (UGIVEN='$UGIVEN', LOGIN='$LOGIN', OBJECTSID='$OBJECTSID', UNAME='$UNAME')"
|
||||
failed_users=$((failed_users + 1))
|
||||
continue
|
||||
fi
|
||||
|
||||
# Create user.ldif from template by replacing placeholders
|
||||
cp "$TEMPLATE_FILE" "$TEMP_LDIF"
|
||||
|
||||
# Use sed to replace placeholders (handle special characters properly)
|
||||
sed -i "s|UGIVEN|$UGIVEN|g" "$TEMP_LDIF"
|
||||
sed -i "s|LOGIN|$LOGIN|g" "$TEMP_LDIF"
|
||||
sed -i "s|OBJECTSID|$OBJECTSID|g" "$TEMP_LDIF"
|
||||
sed -i "s|UNAME|$UNAME|g" "$TEMP_LDIF"
|
||||
|
||||
echo " Created LDIF file for user: $LOGIN"
|
||||
|
||||
# Execute ldbmodify command
|
||||
if ldbmodify -H /var/lib/samba/private/sam.ldb --controls="local_oid:1.3.6.1.4.1.7165.4.3.12:0" "$TEMP_LDIF" 2>/dev/null; then
|
||||
echo " ✓ Successfully created user: $LOGIN"
|
||||
successful_users=$((successful_users + 1))
|
||||
else
|
||||
echo " ✗ Failed to create user: $LOGIN"
|
||||
echo " You may need to run this script as root or check Samba permissions."
|
||||
failed_users=$((failed_users + 1))
|
||||
fi
|
||||
# Set default password for the user as it cannot be read from previous export
|
||||
samba-tool user setpassword "$LOGIN" --newpassword="$DEFAULT_PASSWORD" 2>/dev/null
|
||||
echo ""
|
||||
done
|
||||
|
||||
# Display final statistics
|
||||
echo "========================================="
|
||||
echo "User creation process completed!"
|
||||
echo "Total users processed: $total_users"
|
||||
echo "Successfully created: $successful_users"
|
||||
echo "Failed: $failed_users"
|
||||
echo "========================================="
|
||||
|
||||
# Note about permissions
|
||||
if [[ $failed_users -gt 0 ]]; then
|
||||
echo ""
|
||||
echo "Note: If users failed to be created, you may need to:"
|
||||
echo "1. Run this script as root (sudo ./create_samba_users.sh)"
|
||||
echo "2. Check that Samba4 is properly configured"
|
||||
echo "3. Verify that /var/lib/samba/private/sam.ldb exists and is accessible"
|
||||
fi
|
||||
309
Migration/exportDns.ps1
Normal file
309
Migration/exportDns.ps1
Normal file
@@ -0,0 +1,309 @@
|
||||
# exportDns.ps1 - Export DNS zones and records from Windows AD DNS
|
||||
# Script d'exportation complète DNS pour migration vers Samba4
|
||||
|
||||
Write-Host "=== Début de l'exportation DNS Windows AD ===" -ForegroundColor Green
|
||||
|
||||
# Vérifier que le module DnsServer est disponible
|
||||
try {
|
||||
Import-Module DnsServer -ErrorAction Stop
|
||||
Write-Host "[OK] Module DnsServer chargé avec succès"
|
||||
} catch {
|
||||
Write-Host "[ERREUR] Module DnsServer non disponible. Installer RSAT DNS ou exécuter sur un serveur DNS" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Créer le répertoire d'export
|
||||
$ExportPath = "C:\temp\dns-export"
|
||||
if (!(Test-Path $ExportPath)) {
|
||||
New-Item -ItemType Directory -Path $ExportPath -Force | Out-Null
|
||||
Write-Host " Répertoire d'export créé: $ExportPath"
|
||||
}
|
||||
|
||||
# Initialiser les variables d'export
|
||||
$DnsExport = @{
|
||||
'ExportDate' = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
||||
'ExportedBy' = $env:USERNAME
|
||||
'ServerName' = $env:COMPUTERNAME
|
||||
'Zones' = @()
|
||||
'Statistics' = @{
|
||||
'TotalZones' = 0
|
||||
'ForwardZones' = 0
|
||||
'ReverseZones' = 0
|
||||
'TotalRecords' = 0
|
||||
}
|
||||
}
|
||||
|
||||
# ===== EXPORT DES ZONES DNS =====
|
||||
Write-Host "`n1. Récupération de toutes les zones DNS..." -ForegroundColor Yellow
|
||||
|
||||
try {
|
||||
$AllZones = Get-DnsServerZone
|
||||
$DnsExport.Statistics.TotalZones = $AllZones.Count
|
||||
Write-Host "[OK] $($AllZones.Count) zones trouvées"
|
||||
|
||||
foreach ($Zone in $AllZones) {
|
||||
Write-Host " Traitement de la zone: $($Zone.ZoneName)" -ForegroundColor Cyan
|
||||
|
||||
# Déterminer le type de zone
|
||||
$ZoneType = "Unknown"
|
||||
$IsReverse = $false
|
||||
|
||||
if ($Zone.ZoneName -like "*.in-addr.arpa" -or $Zone.ZoneName -like "*.ip6.arpa") {
|
||||
$ZoneType = "Reverse"
|
||||
$IsReverse = $true
|
||||
$DnsExport.Statistics.ReverseZones++
|
||||
} elseif ($Zone.ZoneName -eq "." -or $Zone.ZoneName -eq "..") {
|
||||
$ZoneType = "Root"
|
||||
} elseif ($Zone.ZoneName -like "_*") {
|
||||
$ZoneType = "Service"
|
||||
} else {
|
||||
$ZoneType = "Forward"
|
||||
$DnsExport.Statistics.ForwardZones++
|
||||
}
|
||||
|
||||
# Créer l'objet zone
|
||||
$ZoneData = [PSCustomObject]@{
|
||||
'ZoneName' = $Zone.ZoneName
|
||||
'ZoneType' = $ZoneType
|
||||
'IsReverse' = $IsReverse
|
||||
'IsPrimary' = $Zone.ZoneType -eq "Primary"
|
||||
'IsStub' = $Zone.ZoneType -eq "Stub"
|
||||
'IsForwarder' = $Zone.ZoneType -eq "Forwarder"
|
||||
'DynamicUpdate' = $Zone.DynamicUpdate.ToString()
|
||||
'Records' = @()
|
||||
}
|
||||
|
||||
# ===== EXPORT DES ENREGISTREMENTS =====
|
||||
try {
|
||||
$Records = Get-DnsServerResourceRecord -ZoneName $Zone.ZoneName -ErrorAction Stop
|
||||
Write-Host " -> $($Records.Count) enregistrements trouvés"
|
||||
|
||||
foreach ($Record in $Records) {
|
||||
$RecordData = $null
|
||||
$RecordValue = ""
|
||||
|
||||
# Extraire les données selon le type d'enregistrement
|
||||
switch ($Record.RecordType) {
|
||||
"A" {
|
||||
$RecordValue = $Record.RecordData.IPv4Address.ToString()
|
||||
}
|
||||
"AAAA" {
|
||||
$RecordValue = $Record.RecordData.IPv6Address.ToString()
|
||||
}
|
||||
"CNAME" {
|
||||
$RecordValue = $Record.RecordData.HostNameAlias.ToString()
|
||||
}
|
||||
"MX" {
|
||||
$RecordValue = "$($Record.RecordData.Preference):$($Record.RecordData.MailExchange)"
|
||||
}
|
||||
"NS" {
|
||||
$RecordValue = $Record.RecordData.NameServer.ToString()
|
||||
}
|
||||
"PTR" {
|
||||
$RecordValue = $Record.RecordData.PtrDomainName.ToString()
|
||||
}
|
||||
"SRV" {
|
||||
$RecordValue = "$($Record.RecordData.Priority):$($Record.RecordData.Weight):$($Record.RecordData.Port):$($Record.RecordData.DomainName)"
|
||||
}
|
||||
"TXT" {
|
||||
$RecordValue = $Record.RecordData.DescriptiveText -join " "
|
||||
}
|
||||
"SOA" {
|
||||
$RecordValue = "$($Record.RecordData.PrimaryServer):$($Record.RecordData.ResponsiblePerson):$($Record.RecordData.SerialNumber)"
|
||||
}
|
||||
default {
|
||||
$RecordValue = $Record.RecordData.ToString()
|
||||
}
|
||||
}
|
||||
|
||||
# Créer l'objet enregistrement
|
||||
$RecordObj = [PSCustomObject]@{
|
||||
'Name' = if ($Record.HostName -eq "@") { "@" } else { $Record.HostName }
|
||||
'Type' = $Record.RecordType.ToString()
|
||||
'TTL' = $Record.TimeToLive.TotalSeconds
|
||||
'Value' = $RecordValue
|
||||
'Timestamp' = if ($Record.Timestamp) { $Record.Timestamp.ToString("yyyy-MM-dd HH:mm:ss") } else { "Static" }
|
||||
}
|
||||
|
||||
$ZoneData.Records += $RecordObj
|
||||
$DnsExport.Statistics.TotalRecords++
|
||||
}
|
||||
|
||||
} catch {
|
||||
Write-Host " Erreur lors de la lecture des enregistrements: $($_.Exception.Message)" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
$DnsExport.Zones += $ZoneData
|
||||
}
|
||||
|
||||
} catch {
|
||||
Write-Host " Erreur lors de la récupération des zones: $($_.Exception.Message)" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
# ===== EXPORT VERS FICHIERS =====
|
||||
Write-Host "`n2. Export vers fichiers..." -ForegroundColor Yellow
|
||||
|
||||
# Export JSON complet
|
||||
$JsonFile = "$ExportPath\dns_export_complete.json"
|
||||
$DnsExport | ConvertTo-Json -Depth 10 | Out-File -FilePath $JsonFile -Encoding UTF8
|
||||
Write-Host "[OK] Export JSON: $JsonFile"
|
||||
|
||||
# Export CSV des zones
|
||||
$CsvZonesFile = "$ExportPath\dns_zones.csv"
|
||||
$DnsExport.Zones | Select-Object ZoneName, ZoneType, IsReverse, IsPrimary, DynamicUpdate, @{Name='RecordCount';Expression={$_.Records.Count}} |
|
||||
Export-Csv -Path $CsvZonesFile -NoTypeInformation -Encoding UTF8
|
||||
Write-Host "[OK] Export CSV zones: $CsvZonesFile"
|
||||
|
||||
# Export CSV des enregistrements par zone
|
||||
foreach ($Zone in $DnsExport.Zones) {
|
||||
if ($Zone.Records.Count -gt 0) {
|
||||
$SafeZoneName = $Zone.ZoneName -replace '[<>:"/\\|?*]', '_'
|
||||
$CsvRecordsFile = "$ExportPath\dns_records_$SafeZoneName.csv"
|
||||
$Zone.Records | Export-Csv -Path $CsvRecordsFile -NoTypeInformation -Encoding UTF8
|
||||
Write-Host " -> Enregistrements zone $($Zone.ZoneName): $CsvRecordsFile"
|
||||
}
|
||||
}
|
||||
|
||||
# Export BIND format pour zones principales
|
||||
Write-Host "`n3. Export format BIND..." -ForegroundColor Yellow
|
||||
$BindExportPath = "$ExportPath\bind-zones"
|
||||
if (!(Test-Path $BindExportPath)) {
|
||||
New-Item -ItemType Directory -Path $BindExportPath -Force | Out-Null
|
||||
}
|
||||
|
||||
foreach ($Zone in ($DnsExport.Zones | Where-Object {$_.ZoneType -eq "Forward" -and $_.IsPrimary})) {
|
||||
$SafeZoneName = $Zone.ZoneName -replace '[<>:"/\\|?*]', '_'
|
||||
$BindFile = "$BindExportPath\db.$SafeZoneName"
|
||||
|
||||
# Créer le fichier de zone BIND
|
||||
$BindContent = @()
|
||||
$BindContent += "; Zone file for $($Zone.ZoneName)"
|
||||
$BindContent += "; Exported from Windows DNS on $(Get-Date)"
|
||||
$BindContent += "; TTL default: 3600"
|
||||
$BindContent += '$TTL 3600'
|
||||
$BindContent += ""
|
||||
|
||||
# Ajouter les enregistrements
|
||||
foreach ($Record in $Zone.Records) {
|
||||
$Name = if ($Record.Name -eq "@") { "@" } else { $Record.Name }
|
||||
$TTL = if ($Record.TTL -gt 0) { $Record.TTL } else { "3600" }
|
||||
|
||||
switch ($Record.Type) {
|
||||
"A" { $BindContent += "$Name`t$TTL`tIN`tA`t$($Record.Value)" }
|
||||
"AAAA" { $BindContent += "$Name`t$TTL`tIN`tAAAA`t$($Record.Value)" }
|
||||
"CNAME" { $BindContent += "$Name`t$TTL`tIN`tCNAME`t$($Record.Value)" }
|
||||
"MX" {
|
||||
$MxParts = $Record.Value -split ":"
|
||||
$BindContent += "$Name`t$TTL`tIN`tMX`t$($MxParts[0])`t$($MxParts[1])"
|
||||
}
|
||||
"NS" { $BindContent += "$Name`t$TTL`tIN`tNS`t$($Record.Value)" }
|
||||
"TXT" { $BindContent += "$Name`t$TTL`tIN`tTXT`t`"$($Record.Value)`"" }
|
||||
"SRV" {
|
||||
$SrvParts = $Record.Value -split ":"
|
||||
if ($SrvParts.Count -eq 4) {
|
||||
$BindContent += "$Name`t$TTL`tIN`tSRV`t$($SrvParts[0])`t$($SrvParts[1])`t$($SrvParts[2])`t$($SrvParts[3])"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$BindContent | Out-File -FilePath $BindFile -Encoding UTF8
|
||||
Write-Host " -> Zone BIND $($Zone.ZoneName): $BindFile"
|
||||
}
|
||||
|
||||
# ===== SCRIPT D'IMPORT POUR SAMBA =====
|
||||
Write-Host "`n4. Génération du script d'import Samba..." -ForegroundColor Yellow
|
||||
$ImportScript = "$ExportPath\import_dns_samba.sh"
|
||||
$ImportContent = @()
|
||||
$ImportContent += "#!/bin/bash"
|
||||
$ImportContent += "# Script d'import DNS pour Samba4"
|
||||
$ImportContent += "# Généré automatiquement depuis exportDns.ps1"
|
||||
$ImportContent += "# Date: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
|
||||
$ImportContent += ""
|
||||
$ImportContent += "# Vérifier que samba-tool est disponible"
|
||||
$ImportContent += "if ! command -v samba-tool &> /dev/null; then"
|
||||
$ImportContent += " echo 'Erreur: samba-tool non trouvé'"
|
||||
$ImportContent += " exit 1"
|
||||
$ImportContent += "fi"
|
||||
$ImportContent += ""
|
||||
$ImportContent += "# Demander les credentials une seule fois"
|
||||
$ImportContent += "echo '=== Import des zones et enregistrements DNS vers Samba4 ==='"
|
||||
$ImportContent += "echo"
|
||||
$ImportContent += "read -p 'Nom d'\''utilisateur administrateur Samba [Administrator]: ' SAMBA_USER"
|
||||
$ImportContent += "SAMBA_USER=`${SAMBA_USER:-Administrator}"
|
||||
$ImportContent += ""
|
||||
$ImportContent += "echo -n 'Mot de passe pour `$SAMBA_USER: '"
|
||||
$ImportContent += "read -s SAMBA_PASSWORD"
|
||||
$ImportContent += "echo"
|
||||
$ImportContent += ""
|
||||
$ImportContent += "# Vérifier les credentials avant de continuer"
|
||||
$ImportContent += "echo 'Test des credentials...'"
|
||||
$ImportContent += "if ! samba-tool user show '`$SAMBA_USER' --username='`$SAMBA_USER' --password='`$SAMBA_PASSWORD' &>/dev/null; then"
|
||||
$ImportContent += " echo 'Erreur: Credentials invalides ou utilisateur non autorisé'"
|
||||
$ImportContent += " exit 1"
|
||||
$ImportContent += "fi"
|
||||
$ImportContent += "echo '[OK] Credentials validés pour `$SAMBA_USER'"
|
||||
$ImportContent += "echo"
|
||||
$ImportContent += ""
|
||||
$ImportContent += "# Mode dry-run optionnel"
|
||||
$ImportContent += "read -p 'Mode dry-run (afficher les commandes sans les exécuter) ? [y/N]: ' DRY_RUN"
|
||||
$ImportContent += "DRY_RUN=`${DRY_RUN:-N}"
|
||||
$ImportContent += ""
|
||||
$ImportContent += "if [[ '`$DRY_RUN' =~ ^[Yy]`$ ]]; then"
|
||||
$ImportContent += " echo '[INFO] Mode dry-run activé - aucune modification ne sera effectuée'"
|
||||
$ImportContent += " echo"
|
||||
$ImportContent += "fi"
|
||||
$ImportContent += ""
|
||||
$ImportContent += "# Fonction pour exécuter les commandes samba-tool"
|
||||
$ImportContent += "execute_samba_cmd() {"
|
||||
$ImportContent += " local cmd='`$1'"
|
||||
$ImportContent += " if [[ '`$DRY_RUN' =~ ^[Yy]`$ ]]; then"
|
||||
$ImportContent += " echo '[DRY-RUN] `$cmd'"
|
||||
$ImportContent += " else"
|
||||
$ImportContent += " if eval '`$cmd'; then"
|
||||
$ImportContent += " echo ' [OK] `$(echo '`$cmd' | cut -d'\'' '\'' -f5-6)'"
|
||||
$ImportContent += " else"
|
||||
$ImportContent += " echo ' [ERREUR] `$(echo '`$cmd' | cut -d'\'' '\'' -f5-6)'"
|
||||
$ImportContent += " fi"
|
||||
$ImportContent += " fi"
|
||||
$ImportContent += "}"
|
||||
$ImportContent += ""
|
||||
$ImportContent += "echo 'Import des zones et enregistrements DNS vers Samba4...'"
|
||||
$ImportContent += "echo"
|
||||
|
||||
# Générer les commandes pour chaque zone et enregistrement
|
||||
foreach ($Zone in ($DnsExport.Zones | Where-Object {$_.ZoneType -eq "Forward" -and $_.IsPrimary -and $_.ZoneName -ne "." -and $_.ZoneName -ne ".." -and $_.ZoneName -notlike "_*"})) {
|
||||
$ImportContent += "# Zone: $($Zone.ZoneName)"
|
||||
$ImportContent += "echo 'Traitement de la zone: $($Zone.ZoneName)'"
|
||||
$ImportContent += "create_zone_if_not_exists `"$($Zone.ZoneName)`""
|
||||
|
||||
foreach ($Record in $Zone.Records) {
|
||||
if ($Record.Type -eq "A" -and $Record.Name -ne "@" -and $Record.Name -notlike "*._*") {
|
||||
$ImportContent += "execute_samba_cmd 'samba-tool dns add localhost $($Zone.ZoneName) $($Record.Name) A $($Record.Value) --username=`"`$SAMBA_USER`" --password=`"`$SAMBA_PASSWORD`"'"
|
||||
}
|
||||
elseif ($Record.Type -eq "CNAME" -and $Record.Name -notlike "*._*") {
|
||||
$ImportContent += "execute_samba_cmd 'samba-tool dns add localhost $($Zone.ZoneName) $($Record.Name) CNAME $($Record.Value) --username=`"`$SAMBA_USER`" --password=`"`$SAMBA_PASSWORD`"'"
|
||||
}
|
||||
}
|
||||
$ImportContent += ""
|
||||
}
|
||||
|
||||
$ImportContent | Out-File -FilePath $ImportScript -Encoding UTF8
|
||||
Write-Host "[OK] Script d'import Samba: $ImportScript"
|
||||
|
||||
# ===== RÉSUMÉ =====
|
||||
Write-Host "`n=== RÉSUMÉ DE L'EXPORT DNS ===" -ForegroundColor Green
|
||||
Write-Host "Zones totales exportées : $($DnsExport.Statistics.TotalZones)"
|
||||
Write-Host "Zones directes : $($DnsExport.Statistics.ForwardZones)"
|
||||
Write-Host "Zones inverses : $($DnsExport.Statistics.ReverseZones)"
|
||||
Write-Host "Enregistrements totaux : $($DnsExport.Statistics.TotalRecords)"
|
||||
Write-Host ""
|
||||
Write-Host "Fichiers générés :"
|
||||
Write-Host "- Export complet JSON : dns_export_complete.json"
|
||||
Write-Host "- Zones CSV : dns_zones.csv"
|
||||
Write-Host "- Enregistrements CSV : dns_records_*.csv"
|
||||
Write-Host "- Zones BIND : bind-zones/db.*"
|
||||
Write-Host "- Script import Samba : import_dns_samba.sh"
|
||||
Write-Host ""
|
||||
Write-Host "[OK] Export DNS terminé avec succès dans : $ExportPath" -ForegroundColor Green
|
||||
170
Migration/exportDomain.ps1
Normal file
170
Migration/exportDomain.ps1
Normal file
@@ -0,0 +1,170 @@
|
||||
# exportDomain.ps1 - Exécuter sur Windows 2022 AD
|
||||
# Script complet d'exportation vers format csv
|
||||
|
||||
# Installer le module PowerShell-Yaml si nécessaire
|
||||
# Install-Module powershell-yaml -Force
|
||||
|
||||
Write-Host "=== Début de l'extraction Active Directory ==="
|
||||
|
||||
# ===== EXTRACTION DU DOMAINE =====
|
||||
Write-Host "1. Extraction des informations de domaine..."
|
||||
$Domain = Get-ADDomain
|
||||
$DomainData = @{
|
||||
'DomainSID' = $Domain.DomainSID.Value
|
||||
'DomainName' = $Domain.Name
|
||||
'DNSRoot' = $Domain.DNSRoot
|
||||
'NetBIOSName' = $Domain.NetBIOSName
|
||||
'DomainMode' = $Domain.DomainMode.ToString()
|
||||
'ForestMode' = $Domain.Forest
|
||||
'PDCEmulator' = $Domain.PDCEmulator
|
||||
'RIDMaster' = $Domain.RIDMaster
|
||||
'InfrastructureMaster' = $Domain.InfrastructureMaster
|
||||
}
|
||||
|
||||
# ===== EXTRACTION DES UTILISATEURS =====
|
||||
Write-Host "2. Extraction des utilisateurs..."
|
||||
$Users = Get-ADUser -Filter * -Properties *
|
||||
$UserExport = @()
|
||||
|
||||
foreach ($User in $Users) {
|
||||
# Exclure les comptes système par défaut
|
||||
# if ($User.SamAccountName -notmatch '^(Administrator|Guest|krbtgt|DefaultAccount|WDAGUtilityAccount)$') {
|
||||
if ($User.SamAccountName -notmatch '^(Administrator|Guest|Administrateur|Invité|krbtgt|DefaultAccount|WDAGUtilityAccount)$') {
|
||||
$UserData = [PSCustomObject]@{
|
||||
'UGIVEN' = if ($User.GivenName) { $User.GivenName } else { "" }
|
||||
'LOGIN' = $User.SamAccountName
|
||||
'OBJECTSID' = $User.SID.Value
|
||||
'UNAME' = if ($User.Surname) { $User.Surname } else { "" }
|
||||
}
|
||||
$UserExport += $UserData
|
||||
}
|
||||
}
|
||||
|
||||
# ===== EXTRACTION DES ORDINATEURS =====
|
||||
Write-Host "3. Extraction des ordinateurs..."
|
||||
$Computers = Get-ADComputer -Filter * -Properties *
|
||||
$ComputerExport = @()
|
||||
|
||||
foreach ($Computer in $Computers) {
|
||||
# Exclure les contrôleurs de domaine
|
||||
if ($Computer.Name -notmatch '^(DC|DOMAIN)') {
|
||||
$ComputerData = [PSCustomObject]@{
|
||||
'NAME' = $Computer.Name
|
||||
'OBJECTSID' = $Computer.SID.Value
|
||||
}
|
||||
$ComputerExport += $ComputerData
|
||||
}
|
||||
}
|
||||
|
||||
# ===== EXTRACTION DES GROUPES =====
|
||||
Write-Host "4. Extraction des groupes..."
|
||||
$Groups = Get-ADGroup -Filter * -Properties *
|
||||
$GroupExport = @()
|
||||
|
||||
foreach ($Group in $Groups) {
|
||||
# Exclure les groupes système par défaut
|
||||
$SystemGroups = @(
|
||||
# Groupes de domaine en français
|
||||
'Admins du domaine', 'Utilisateurs du domaine', 'Invités du domaine', 'Ordinateurs du domaine',
|
||||
'Administrateurs', 'Utilisateurs', 'Invités', 'Utilisateurs avec pouvoirs', 'Opérateurs de sauvegarde',
|
||||
'Duplicateurs', 'Opérateurs de configuration réseau', 'Utilisateurs de l''Analyseur de performances',
|
||||
'Utilisateurs du journal de performances', 'Utilisateurs du modèle COM distribué', 'IIS_IUSRS',
|
||||
'Opérateurs de chiffrement', 'Lecteurs des journaux d''événements', 'Accès DCOM service de certificats',
|
||||
'Serveurs Accès Distant RDS', 'Serveurs RDS Endpoint', 'Serveurs Gestion RDS',
|
||||
'Administrateurs Hyper-V', 'Opérateurs d''assistance de contrôle d''accès',
|
||||
'Utilisateurs de gestion à distance', 'Administrateurs de réplication de stockage',
|
||||
'Administrateurs du schéma', 'Administrateurs de l''entreprise', 'Éditeurs de certificats', 'Contrôleurs de domaine',
|
||||
'Propriétaires créateurs de la stratégie de groupe', 'Serveurs RAS et IAS', 'Opérateurs de serveur',
|
||||
'Opérateurs de compte', 'Opérateurs d''impression', 'Accès compatible pré-Windows 2000',
|
||||
'Générateurs d''approbations de forêt entrante', 'Groupe d''accès d''autorisation Windows',
|
||||
'Serveurs de licences des services Terminal Server', 'Utilisateurs DHCP', 'Administrateurs DHCP',
|
||||
'DnsAdmins', 'DnsUpdateProxy', 'Utilisateurs WINS', 'IIS_WPG',
|
||||
'Groupe de réplication dont le mot de passe RODC est refusé', 'Groupe de réplication dont le mot de passe RODC est autorisé',
|
||||
'Contrôleurs de domaine d''entreprise en lecture seule', 'Contrôleurs de domaine en lecture seule',
|
||||
'Contrôleurs de domaine clonables', 'Utilisateurs protégés', 'Administrateurs clés',
|
||||
'Administrateurs clés Enterprise',
|
||||
# Noms anglais pour compatibilité (au cas où certains groupes gardent leur nom anglais)
|
||||
'Domain Admins', 'Domain Users', 'Domain Guests', 'Domain Computers',
|
||||
'Administrators', 'Users', 'Guests', 'Power Users', 'Backup Operators',
|
||||
'Replicator', 'Network Configuration Operators', 'Performance Monitor Users',
|
||||
'Performance Log Users', 'Distributed COM Users',
|
||||
'Cryptographic Operators', 'Event Log Readers', 'Certificate Service DCOM Access',
|
||||
'RDS Remote Access Servers', 'RDS Endpoint Servers', 'RDS Management Servers',
|
||||
'Hyper-V Administrators', 'Access Control Assistance Operators',
|
||||
'Remote Management Users', 'Storage Replica Administrators',
|
||||
'Schema Admins', 'Enterprise Admins', 'Cert Publishers', 'Domain Controllers',
|
||||
'Group Policy Creator Owners', 'RAS and IAS Servers', 'Server Operators',
|
||||
'Account Operators', 'Print Operators', 'Pre-Windows 2000 Compatible Access',
|
||||
'Incoming Forest Trust Builders', 'Windows Authorization Access Group',
|
||||
'Terminal Server License Servers', 'DHCP Users', 'DHCP Administrators',
|
||||
'Denied RODC Password Replication Group', 'Allowed RODC Password Replication Group',
|
||||
'Enterprise Read-only Domain Controllers', 'Read-only Domain Controllers',
|
||||
'Cloneable Domain Controllers', 'Protected Users', 'Key Admins',
|
||||
'Enterprise Key Admins'
|
||||
)
|
||||
|
||||
if ($Group.Name -notin $SystemGroups -and $Group.SamAccountName -notmatch '\$$') {
|
||||
$GroupData = [PSCustomObject]@{
|
||||
'NAME' = $Group.Name
|
||||
'OBJECTSID' = $Group.SID.Value
|
||||
}
|
||||
$GroupExport += $GroupData
|
||||
}
|
||||
}
|
||||
|
||||
# ===== CONSOLIDATION DES DONNÉES =====
|
||||
Write-Host "5. Consolidation des donnees..."
|
||||
$ConsolidatedData = @{
|
||||
'ExportDate' = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
||||
'ExportedBy' = $env:USERNAME
|
||||
'Domain' = $DomainData
|
||||
'Users' = $UserExport
|
||||
'Computers' = $ComputerExport
|
||||
'Groups' = $GroupExport
|
||||
'Statistics' = @{
|
||||
'TotalUsers' = $UserExport.Count
|
||||
'TotalComputers' = $ComputerExport.Count
|
||||
'TotalGroups' = $GroupExport.Count
|
||||
}
|
||||
}
|
||||
|
||||
# Afficher un aperçu pour vérification
|
||||
Write-Host "Aperçu des données exportées :"
|
||||
Write-Host "Premier utilisateur : $($UserExport[0].LOGIN) - $($UserExport[0].UGIVEN) $($UserExport[0].UNAME)"
|
||||
if ($ComputerExport.Count -gt 0) {
|
||||
Write-Host "Premier ordinateur : $($ComputerExport[0].NAME)"
|
||||
}
|
||||
if ($GroupExport.Count -gt 0) {
|
||||
Write-Host "Premier groupe : $($GroupExport[0].NAME)"
|
||||
}
|
||||
|
||||
# ===== EXPORT VERS CSV =====
|
||||
Write-Host "6. Export vers fichiers CSV..."
|
||||
|
||||
# Créer le répertoire temp s'il n'existe pas
|
||||
if (!(Test-Path "C:\temp")) {
|
||||
New-Item -ItemType Directory -Path "C:\temp" -Force
|
||||
}
|
||||
|
||||
# Export complet en JSON pour référence
|
||||
$ConsolidatedData | ConvertTo-Json -Depth 20 | Out-File -FilePath "C:\temp\ad_export_complete.json" -Encoding UTF8
|
||||
|
||||
# Exports individuels en CSV
|
||||
$UserExport | Export-Csv -Path "C:\temp\users.csv" -NoTypeInformation -Encoding UTF8
|
||||
$ComputerExport | Export-Csv -Path "C:\temp\computers.csv" -NoTypeInformation -Encoding UTF8
|
||||
$GroupExport | Export-Csv -Path "C:\temp\groups.csv" -NoTypeInformation -Encoding UTF8
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "=== Resume ==="
|
||||
Write-Host "Utilisateurs exportes : $($UserExport.Count)"
|
||||
Write-Host "Ordinateurs exportes : $($ComputerExport.Count)"
|
||||
Write-Host "Groupes exportes : $($GroupExport.Count)"
|
||||
Write-Host "SID de domaine : $($DomainData.DomainSID)"
|
||||
Write-Host ""
|
||||
Write-Host "Fichiers generes :"
|
||||
Write-Host "- C:\temp\ad_export_complete.json (export complet)"
|
||||
Write-Host "- C:\temp\users.csv (format CSV)"
|
||||
Write-Host "- C:\temp\computers.csv (format CSV)"
|
||||
Write-Host "- C:\temp\groups.csv (format CSV)"
|
||||
Write-Host ""
|
||||
Write-Host "Extraction terminee avec succes"
|
||||
215
Migration/exportDomainComplete.ps1
Normal file
215
Migration/exportDomainComplete.ps1
Normal file
@@ -0,0 +1,215 @@
|
||||
# exportDomain.ps1 - Exécuter sur Windows 2022 AD
|
||||
# Script complet d'exportation vers format YAML
|
||||
|
||||
# Installer le module PowerShell-Yaml si nécessaire
|
||||
# Install-Module powershell-yaml -Force
|
||||
|
||||
# Fonction pour convertir en YAML
|
||||
function ConvertTo-Yaml {
|
||||
param($InputObject)
|
||||
return ConvertTo-Json $InputObject -Depth 10 | ConvertFrom-Json | ConvertTo-Yaml
|
||||
}
|
||||
|
||||
Write-Host "=== Début de l'extraction Active Directory ==="
|
||||
|
||||
# ===== EXTRACTION DU DOMAINE =====
|
||||
Write-Host "1. Extraction des informations de domaine..."
|
||||
$Domain = Get-ADDomain
|
||||
$DomainData = @{
|
||||
'DomainSID' = $Domain.DomainSID.Value
|
||||
'DomainName' = $Domain.Name
|
||||
'DNSRoot' = $Domain.DNSRoot
|
||||
'NetBIOSName' = $Domain.NetBIOSName
|
||||
'DomainMode' = $Domain.DomainMode.ToString()
|
||||
'ForestMode' = $Domain.Forest
|
||||
'PDCEmulator' = $Domain.PDCEmulator
|
||||
'RIDMaster' = $Domain.RIDMaster
|
||||
'InfrastructureMaster' = $Domain.InfrastructureMaster
|
||||
}
|
||||
|
||||
# ===== EXTRACTION DES UTILISATEURS =====
|
||||
Write-Host "2. Extraction des utilisateurs..."
|
||||
$Users = Get-ADUser -Filter * -Properties *
|
||||
$UserExport = @()
|
||||
|
||||
foreach ($User in $Users) {
|
||||
# Exclure les comptes système par défaut
|
||||
# if ($User.SamAccountName -notmatch '^(Administrator|Guest|krbtgt|DefaultAccount|WDAGUtilityAccount)$') {
|
||||
if ($User.SamAccountName -notmatch '^(Administrator|Guest|krbtgt|DefaultAccount|WDAGUtilityAccount)$') {
|
||||
$UserData = @{
|
||||
'SamAccountName' = $User.SamAccountName
|
||||
'Name' = $User.Name
|
||||
'GivenName' = $User.GivenName
|
||||
'Surname' = $User.Surname
|
||||
'DisplayName' = $User.DisplayName
|
||||
'UserPrincipalName' = $User.UserPrincipalName
|
||||
'EmailAddress' = $User.EmailAddress
|
||||
'Description' = $User.Description
|
||||
'Enabled' = $User.Enabled
|
||||
'PasswordNeverExpires' = $User.PasswordNeverExpires
|
||||
'PasswordLastSet' = $User.PasswordLastSet
|
||||
'LastLogonDate' = $User.LastLogonDate
|
||||
'SID' = $User.SID.Value
|
||||
'DistinguishedName' = $User.DistinguishedName
|
||||
'HomeDirectory' = $User.HomeDirectory
|
||||
'HomeDrive' = $User.HomeDrive
|
||||
'ProfilePath' = $User.ProfilePath
|
||||
'ScriptPath' = $User.ScriptPath
|
||||
'MemberOf' = $User.MemberOf
|
||||
}
|
||||
$UserExport += $UserData
|
||||
}
|
||||
}
|
||||
|
||||
# ===== EXTRACTION DES ORDINATEURS =====
|
||||
Write-Host "3. Extraction des ordinateurs..."
|
||||
$Computers = Get-ADComputer -Filter * -Properties *
|
||||
$ComputerExport = @()
|
||||
|
||||
foreach ($Computer in $Computers) {
|
||||
# Exclure les contrôleurs de domaine
|
||||
if ($Computer.Name -notmatch '^(DC|DOMAIN)') {
|
||||
$ComputerData = @{
|
||||
'Name' = $Computer.Name
|
||||
'SamAccountName' = $Computer.SamAccountName
|
||||
'DNSHostName' = $Computer.DNSHostName
|
||||
'Description' = $Computer.Description
|
||||
'Enabled' = $Computer.Enabled
|
||||
'SID' = $Computer.SID.Value
|
||||
'DistinguishedName' = $Computer.DistinguishedName
|
||||
'OperatingSystem' = $Computer.OperatingSystem
|
||||
'OperatingSystemVersion' = $Computer.OperatingSystemVersion
|
||||
'OperatingSystemServicePack' = $Computer.OperatingSystemServicePack
|
||||
'LastLogonDate' = $Computer.LastLogonDate
|
||||
'PasswordLastSet' = $Computer.PasswordLastSet
|
||||
'Location' = $Computer.Location
|
||||
'ManagedBy' = $Computer.ManagedBy
|
||||
}
|
||||
$ComputerExport += $ComputerData
|
||||
}
|
||||
}
|
||||
|
||||
# ===== EXTRACTION DES GROUPES =====
|
||||
Write-Host "4. Extraction des groupes..."
|
||||
$Groups = Get-ADGroup -Filter * -Properties *
|
||||
$GroupExport = @()
|
||||
|
||||
foreach ($Group in $Groups) {
|
||||
# Exclure les groupes système par défaut
|
||||
# $SystemGroups = @(
|
||||
# 'Domain Admins', 'Domain Users', 'Domain Guests', 'Domain Computers',
|
||||
# 'Administrators', 'Users', 'Guests', 'Power Users', 'Backup Operators',
|
||||
# 'Replicator', 'Network Configuration Operators', 'Performance Monitor Users',
|
||||
# 'Performance Log Users', 'Distributed COM Users', 'IIS_IUSRS',
|
||||
# 'Cryptographic Operators', 'Event Log Readers', 'Certificate Service DCOM Access',
|
||||
# 'RDS Remote Access Servers', 'RDS Endpoint Servers', 'RDS Management Servers',
|
||||
# 'Hyper-V Administrators', 'Access Control Assistance Operators',
|
||||
# 'Remote Management Users', 'Storage Replica Administrators',
|
||||
# 'Schema Admins', 'Enterprise Admins', 'Cert Publishers', 'Domain Controllers',
|
||||
# 'Group Policy Creator Owners', 'RAS and IAS Servers', 'Server Operators',
|
||||
# 'Account Operators', 'Print Operators', 'Pre-Windows 2000 Compatible Access',
|
||||
# 'Incoming Forest Trust Builders', 'Windows Authorization Access Group',
|
||||
# 'Terminal Server License Servers', 'DHCP Users', 'DHCP Administrators',
|
||||
# 'DnsAdmins', 'DnsUpdateProxy', 'WINS Users', 'IIS_WPG',
|
||||
# 'Denied RODC Password Replication Group', 'Allowed RODC Password Replication Group',
|
||||
# 'Enterprise Read-only Domain Controllers', 'Read-only Domain Controllers',
|
||||
# 'Cloneable Domain Controllers', 'Protected Users', 'Key Admins',
|
||||
# 'Enterprise Key Admins'
|
||||
# )
|
||||
$SystemGroups = @(
|
||||
'Domain Admins', 'Domain Users', 'Domain Guests', 'Domain Computers',
|
||||
'Administrators', 'Users', 'Guests', 'Power Users', 'Backup Operators',
|
||||
'Replicator', 'Network Configuration Operators', 'Performance Monitor Users',
|
||||
'Performance Log Users', 'Distributed COM Users', 'IIS_IUSRS',
|
||||
'Cryptographic Operators', 'Event Log Readers', 'Certificate Service DCOM Access',
|
||||
'RDS Remote Access Servers', 'RDS Endpoint Servers', 'RDS Management Servers',
|
||||
'Hyper-V Administrators', 'Access Control Assistance Operators',
|
||||
'Remote Management Users', 'Storage Replica Administrators',
|
||||
'Schema Admins', 'Enterprise Admins', 'Cert Publishers', 'Domain Controllers',
|
||||
'Group Policy Creator Owners', 'RAS and IAS Servers', 'Server Operators',
|
||||
'Account Operators', 'Print Operators', 'Pre-Windows 2000 Compatible Access',
|
||||
'Incoming Forest Trust Builders', 'Windows Authorization Access Group',
|
||||
'Terminal Server License Servers', 'DHCP Users', 'DHCP Administrators',
|
||||
'DnsAdmins', 'DnsUpdateProxy', 'WINS Users', 'IIS_WPG',
|
||||
'Denied RODC Password Replication Group', 'Allowed RODC Password Replication Group',
|
||||
'Enterprise Read-only Domain Controllers', 'Read-only Domain Controllers',
|
||||
'Cloneable Domain Controllers', 'Protected Users', 'Key Admins',
|
||||
'Enterprise Key Admins'
|
||||
)
|
||||
|
||||
if ($Group.Name -notin $SystemGroups -and $Group.SamAccountName -notmatch '\$$') {
|
||||
# Obtenir les membres du groupe
|
||||
$Members = Get-ADGroupMember -Identity $Group -Recursive -ErrorAction SilentlyContinue
|
||||
$MemberList = @()
|
||||
foreach ($Member in $Members) {
|
||||
$MemberList += @{
|
||||
'Name' = $Member.Name
|
||||
'SamAccountName' = $Member.SamAccountName
|
||||
'ObjectClass' = $Member.ObjectClass
|
||||
'DistinguishedName' = $Member.DistinguishedName
|
||||
}
|
||||
}
|
||||
|
||||
$GroupData = @{
|
||||
'Name' = $Group.Name
|
||||
'SamAccountName' = $Group.SamAccountName
|
||||
'Description' = $Group.Description
|
||||
'GroupCategory' = $Group.GroupCategory.ToString()
|
||||
'GroupScope' = $Group.GroupScope.ToString()
|
||||
'SID' = $Group.SID.Value
|
||||
'DistinguishedName' = $Group.DistinguishedName
|
||||
'ManagedBy' = $Group.ManagedBy
|
||||
'Members' = $MemberList
|
||||
'MemberOf' = $Group.MemberOf
|
||||
}
|
||||
$GroupExport += $GroupData
|
||||
}
|
||||
}
|
||||
|
||||
# ===== CONSOLIDATION DES DONNÉES =====
|
||||
Write-Host "5. Consolidation des donnees..."
|
||||
$ConsolidatedData = @{
|
||||
'ExportDate' = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
||||
'ExportedBy' = $env:USERNAME
|
||||
'Domain' = $DomainData
|
||||
'Users' = $UserExport
|
||||
'Computers' = $ComputerExport
|
||||
'Groups' = $GroupExport
|
||||
'Statistics' = @{
|
||||
'TotalUsers' = $UserExport.Count
|
||||
'TotalComputers' = $ComputerExport.Count
|
||||
'TotalGroups' = $GroupExport.Count
|
||||
}
|
||||
}
|
||||
|
||||
# ===== EXPORT VERS YAML =====
|
||||
Write-Host "6. Export vers fichiers..."
|
||||
|
||||
# Créer le répertoire temp s'il n'existe pas
|
||||
if (!(Test-Path "C:\temp")) {
|
||||
New-Item -ItemType Directory -Path "C:\temp" -Force
|
||||
}
|
||||
|
||||
# Export principal en YAML
|
||||
# Fallback en JSON si YAML n'est pas disponible
|
||||
$ConsolidatedData | ConvertTo-Json -Depth 20 | Out-File -FilePath "C:\temp\ad_export_complete.json" -Encoding UTF8
|
||||
|
||||
# Exports individuels pour compatibilité
|
||||
$UserExport | ConvertTo-Json -Depth 5 | Out-File -FilePath "C:\temp\users_export.json" -Encoding UTF8
|
||||
$ComputerExport | ConvertTo-Json -Depth 5 | Out-File -FilePath "C:\temp\computers_export.json" -Encoding UTF8
|
||||
$GroupExport | ConvertTo-Json -Depth 5 | Out-File -FilePath "C:\temp\groups_export.json" -Encoding UTF8
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "=== Resume ==="
|
||||
Write-Host "Utilisateurs exportes : $($UserExport.Count)"
|
||||
Write-Host "Ordinateurs exportes : $($ComputerExport.Count)"
|
||||
Write-Host "Groupes exportes : $($GroupExport.Count)"
|
||||
Write-Host "SID de domaine : $($DomainData.DomainSID)"
|
||||
Write-Host ""
|
||||
Write-Host "Fichiers generes :"
|
||||
Write-Host "- C:\temp\ad_export_complete.yaml (ou .json)"
|
||||
Write-Host "- C:\temp\users_export.json"
|
||||
Write-Host "- C:\temp\computers_export.json"
|
||||
Write-Host "- C:\temp\groups_export.json"
|
||||
Write-Host ""
|
||||
Write-Host "Extraction terminee avec succes "
|
||||
12
Migration/group.ldif.orig
Normal file
12
Migration/group.ldif.orig
Normal file
@@ -0,0 +1,12 @@
|
||||
dn: CN=NAME,CN=Users,DC=aipice,DC=local
|
||||
objectClass: top
|
||||
objectClass: group
|
||||
cn: NAME
|
||||
description: NAME
|
||||
instanceType: 4
|
||||
name: NAME
|
||||
objectSid: OBJECTSID
|
||||
sAMAccountName: NAME
|
||||
groupType: -2147483644
|
||||
objectCategory: CN=Group,CN=Schema,CN=Configuration,DC=aipice,DC=local
|
||||
distinguishedName: CN=NAME,CN=Users,DC=aipice,DC=local
|
||||
BIN
Migration/images/cloner.png
Executable file
BIN
Migration/images/cloner.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 7.6 KiB |
BIN
Migration/images/cloner02.png
Executable file
BIN
Migration/images/cloner02.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
BIN
Migration/images/cloudinit-01.png
Executable file
BIN
Migration/images/cloudinit-01.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 8.2 KiB |
BIN
Migration/images/cloudinit-02.png
Executable file
BIN
Migration/images/cloudinit-02.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
267
Migration/importDns.sh
Executable file
267
Migration/importDns.sh
Executable file
@@ -0,0 +1,267 @@
|
||||
#!/bin/bash
|
||||
# importDns.sh - Import DNS zones and records from CSV files to Samba4
|
||||
# Utilise les fichiers CSV générés par exportDns.ps1
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Configuration
|
||||
DNS_DIR="Transfert/Dns"
|
||||
ZONES_CSV="$DNS_DIR/dns_zones.csv"
|
||||
|
||||
# Couleurs pour l'affichage
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Fonction d'affichage avec couleurs
|
||||
log_info() {
|
||||
echo -e "${BLUE}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_success() {
|
||||
echo -e "${GREEN}[OK]${NC} $1"
|
||||
}
|
||||
|
||||
log_warning() {
|
||||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERREUR]${NC} $1"
|
||||
}
|
||||
|
||||
# Vérifications préalables
|
||||
check_prerequisites() {
|
||||
log_info "Vérification des prérequis..."
|
||||
|
||||
# Vérifier que samba-tool est disponible
|
||||
if ! command -v samba-tool &> /dev/null; then
|
||||
log_error "samba-tool non trouvé. Assurez-vous que Samba4 est installé."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Vérifier que le répertoire DNS existe
|
||||
if [[ ! -d "$DNS_DIR" ]]; then
|
||||
log_error "Répertoire DNS non trouvé: $DNS_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Vérifier que le fichier des zones existe
|
||||
if [[ ! -f "$ZONES_CSV" ]]; then
|
||||
log_error "Fichier des zones non trouvé: $ZONES_CSV"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_success "Prérequis validés"
|
||||
}
|
||||
|
||||
# Demander les credentials
|
||||
get_credentials() {
|
||||
log_info "Configuration des credentials Samba4"
|
||||
echo
|
||||
|
||||
read -p "Nom d'utilisateur administrateur Samba [Administrator]: " SAMBA_USER
|
||||
SAMBA_USER=${SAMBA_USER:-Administrator}
|
||||
|
||||
echo -n "Mot de passe pour $SAMBA_USER: "
|
||||
read -s SAMBA_PASSWORD
|
||||
echo
|
||||
echo
|
||||
|
||||
# Vérifier les credentials
|
||||
log_info "Test des credentials..."
|
||||
if ! samba-tool user show "$SAMBA_USER" --username="$SAMBA_USER" --password="$SAMBA_PASSWORD" &>/dev/null; then
|
||||
log_error "Credentials invalides ou utilisateur non autorisé"
|
||||
exit 1
|
||||
fi
|
||||
log_success "Credentials validés pour $SAMBA_USER"
|
||||
echo
|
||||
}
|
||||
|
||||
# Demander le mode d'exécution
|
||||
get_execution_mode() {
|
||||
echo "Modes d'exécution disponibles:"
|
||||
echo " 1. Dry-run (afficher les commandes sans les exécuter)"
|
||||
echo " 2. Import réel (exécuter les commandes)"
|
||||
echo
|
||||
|
||||
while true; do
|
||||
read -p "Choisissez le mode [1/2]: " MODE_CHOICE
|
||||
case $MODE_CHOICE in
|
||||
1)
|
||||
DRY_RUN=true
|
||||
log_info "Mode dry-run activé - aucune modification ne sera effectuée"
|
||||
break
|
||||
;;
|
||||
2)
|
||||
DRY_RUN=false
|
||||
log_info "Mode import réel activé"
|
||||
break
|
||||
;;
|
||||
*)
|
||||
echo "Choix invalide. Entrez 1 ou 2."
|
||||
;;
|
||||
esac
|
||||
done
|
||||
echo
|
||||
}
|
||||
|
||||
# Fonction pour exécuter les commandes samba-tool
|
||||
execute_samba_cmd() {
|
||||
local cmd="$1"
|
||||
local description="$2"
|
||||
|
||||
if [[ "$DRY_RUN" == "true" ]]; then
|
||||
echo " [DRY-RUN] $description"
|
||||
echo " → $cmd"
|
||||
else
|
||||
if eval "$cmd" &>/dev/null; then
|
||||
log_success "$description"
|
||||
else
|
||||
log_error "$description"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Créer une zone DNS si elle n'existe pas
|
||||
create_zone_if_not_exists() {
|
||||
local zone_name="$1"
|
||||
|
||||
if [[ "$DRY_RUN" == "true" ]]; then
|
||||
echo " [DRY-RUN] Vérification/création de la zone: $zone_name"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Vérifier si la zone existe déjà
|
||||
if samba-tool dns query localhost "$zone_name" @ SOA --username="$SAMBA_USER" --password="$SAMBA_PASSWORD" &>/dev/null; then
|
||||
log_info "Zone $zone_name existe déjà"
|
||||
else
|
||||
log_info "Création de la zone: $zone_name"
|
||||
if samba-tool dns zonecreate localhost "$zone_name" --username="$SAMBA_USER" --password="$SAMBA_PASSWORD" &>/dev/null; then
|
||||
log_success "Zone $zone_name créée avec succès"
|
||||
else
|
||||
log_error "Impossible de créer la zone $zone_name"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Traiter les enregistrements d'une zone
|
||||
process_zone_records() {
|
||||
local zone_name="$1"
|
||||
local records_file="$DNS_DIR/dns_records_${zone_name}.csv"
|
||||
|
||||
if [[ ! -f "$records_file" ]]; then
|
||||
log_warning "Fichier d'enregistrements non trouvé: $records_file"
|
||||
return 0
|
||||
fi
|
||||
|
||||
log_info "Traitement des enregistrements pour la zone: $zone_name"
|
||||
|
||||
local record_count=0
|
||||
local success_count=0
|
||||
|
||||
# Lire le fichier CSV ligne par ligne (en sautant l'en-tête)
|
||||
while IFS=',' read -r name type ttl value timestamp; do
|
||||
# Supprimer les guillemets
|
||||
name=$(echo "$name" | tr -d '"')
|
||||
type=$(echo "$type" | tr -d '"')
|
||||
ttl=$(echo "$ttl" | tr -d '"')
|
||||
value=$(echo "$value" | tr -d '"')
|
||||
|
||||
# Ignorer l'en-tête
|
||||
if [[ "$name" == "Name" ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Ignorer les enregistrements système et spéciaux
|
||||
if [[ "$name" == "@" ]] || [[ "$name" =~ ^_.*$ ]] || [[ "$type" == "SOA" ]] || [[ "$type" == "NS" ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Construire la commande samba-tool
|
||||
local cmd="samba-tool dns add localhost \"$zone_name\" \"$name\" $type \"$value\" --username=\"$SAMBA_USER\" --password=\"$SAMBA_PASSWORD\""
|
||||
local description="Ajout enregistrement: $name ($type) → $value"
|
||||
|
||||
((record_count++))
|
||||
|
||||
if execute_samba_cmd "$cmd" "$description"; then
|
||||
((success_count++))
|
||||
fi
|
||||
|
||||
done < "$records_file"
|
||||
|
||||
if [[ "$DRY_RUN" == "false" ]]; then
|
||||
log_info "Zone $zone_name: $success_count/$record_count enregistrements traités avec succès"
|
||||
fi
|
||||
echo
|
||||
}
|
||||
|
||||
# Fonction principale d'import
|
||||
import_dns_zones() {
|
||||
log_info "Début de l'import DNS depuis les fichiers CSV"
|
||||
echo
|
||||
|
||||
local total_zones=0
|
||||
local processed_zones=0
|
||||
|
||||
# Lire le fichier des zones (en sautant l'en-tête)
|
||||
while IFS=',' read -r zone_name zone_type is_reverse is_primary dynamic_update record_count; do
|
||||
# Supprimer les guillemets
|
||||
zone_name=$(echo "$zone_name" | tr -d '"')
|
||||
zone_type=$(echo "$zone_type" | tr -d '"')
|
||||
is_primary=$(echo "$is_primary" | tr -d '"')
|
||||
|
||||
# Ignorer l'en-tête
|
||||
if [[ "$zone_name" == "ZoneName" ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Traiter seulement les zones Forward Primary (pas les reverse)
|
||||
if [[ "$zone_type" != "Forward" ]] || [[ "$is_primary" != "True" ]]; then
|
||||
log_info "Ignorer la zone: $zone_name (Type: $zone_type, Primary: $is_primary)"
|
||||
continue
|
||||
fi
|
||||
|
||||
((total_zones++))
|
||||
|
||||
echo "==================================================================================="
|
||||
log_info "Traitement de la zone: $zone_name"
|
||||
echo
|
||||
|
||||
# Créer la zone si nécessaire
|
||||
if create_zone_if_not_exists "$zone_name"; then
|
||||
# Traiter les enregistrements de la zone
|
||||
process_zone_records "$zone_name"
|
||||
((processed_zones++))
|
||||
else
|
||||
log_error "Échec de la création/vérification de la zone: $zone_name"
|
||||
fi
|
||||
|
||||
done < "$ZONES_CSV"
|
||||
|
||||
echo "==================================================================================="
|
||||
log_success "Import terminé: $processed_zones/$total_zones zones traitées"
|
||||
}
|
||||
|
||||
# Fonction principale
|
||||
main() {
|
||||
echo "==================================================================================="
|
||||
echo " IMPORT DNS VERS SAMBA4"
|
||||
echo "==================================================================================="
|
||||
echo
|
||||
|
||||
check_prerequisites
|
||||
get_credentials
|
||||
get_execution_mode
|
||||
import_dns_zones
|
||||
|
||||
echo
|
||||
log_success "Script d'import DNS terminé avec succès !"
|
||||
}
|
||||
|
||||
# Exécution du script principal
|
||||
main "$@"
|
||||
66
Migration/traduction.txt
Normal file
66
Migration/traduction.txt
Normal file
@@ -0,0 +1,66 @@
|
||||
"NAME","OBJECTSID"
|
||||
"Administrateurs","S-1-5-32-544"
|
||||
"Utilisateurs","S-1-5-32-545"
|
||||
"Invités","S-1-5-32-546"
|
||||
"Opérateurs d’impression","S-1-5-32-550"
|
||||
"Opérateurs de sauvegarde","S-1-5-32-551"
|
||||
"Duplicateurs","S-1-5-32-552"
|
||||
"Utilisateurs du Bureau à distance","S-1-5-32-555"
|
||||
"Opérateurs de configuration réseau","S-1-5-32-556"
|
||||
"Utilisateurs de l’Analyseur de performances","S-1-5-32-558"
|
||||
"Utilisateurs du journal de performances","S-1-5-32-559"
|
||||
"Utilisateurs du modèle COM distribué","S-1-5-32-562"
|
||||
"Opérateurs de chiffrement","S-1-5-32-569"
|
||||
"Lecteurs des journaux d’événements","S-1-5-32-573"
|
||||
"Accès DCOM service de certificats","S-1-5-32-574"
|
||||
"Serveurs Accès Distant RDS","S-1-5-32-575"
|
||||
"Serveurs RDS Endpoint","S-1-5-32-576"
|
||||
"Serveurs Gestion RDS","S-1-5-32-577"
|
||||
"Administrateurs Hyper-V","S-1-5-32-578"
|
||||
"Opérateurs d'assistance de contrôle d'accès","S-1-5-32-579"
|
||||
"Utilisateurs de gestion à distance","S-1-5-32-580"
|
||||
"Ordinateurs du domaine","S-1-5-21-4102117871-3715726371-348907982-515"
|
||||
"Contrôleurs de domaine","S-1-5-21-4102117871-3715726371-348907982-516"
|
||||
"Administrateurs du schéma","S-1-5-21-4102117871-3715726371-348907982-518"
|
||||
"Administrateurs de l’entreprise","S-1-5-21-4102117871-3715726371-348907982-519"
|
||||
"Éditeurs de certificats","S-1-5-21-4102117871-3715726371-348907982-517"
|
||||
"Admins du domaine","S-1-5-21-4102117871-3715726371-348907982-512"
|
||||
"Utilisateurs du domaine","S-1-5-21-4102117871-3715726371-348907982-513"
|
||||
"Invités du domaine","S-1-5-21-4102117871-3715726371-348907982-514"
|
||||
"Propriétaires créateurs de la stratégie de groupe","S-1-5-21-4102117871-3715726371-348907982-520"
|
||||
"Serveurs RAS et IAS","S-1-5-21-4102117871-3715726371-348907982-553"
|
||||
"Opérateurs de serveur","S-1-5-32-549"
|
||||
"Opérateurs de compte","S-1-5-32-548"
|
||||
"Accès compatible pré-Windows 2000","S-1-5-32-554"
|
||||
"Générateurs d’approbations de forêt entrante","S-1-5-32-557"
|
||||
"Groupe d’accès d’autorisation Windows","S-1-5-32-560"
|
||||
"Serveurs de licences des services Terminal Server","S-1-5-32-561"
|
||||
"Groupe de réplication dont le mot de passe RODC est autorisé","S-1-5-21-4102117871-3715726371-348907982-571"
|
||||
"Groupe de réplication dont le mot de passe RODC est refusé","S-1-5-21-4102117871-3715726371-348907982-572"
|
||||
"Contrôleurs de domaine en lecture seule","S-1-5-21-4102117871-3715726371-348907982-521"
|
||||
"Contrôleurs de domaine d’entreprise en lecture seule","S-1-5-21-4102117871-3715726371-348907982-498"
|
||||
"Contrôleurs de domaine clonables","S-1-5-21-4102117871-3715726371-348907982-522"
|
||||
"Administrateurs clés","S-1-5-21-4102117871-3715726371-348907982-526"
|
||||
"Administrateurs clés Enterprise","S-1-5-21-4102117871-3715726371-348907982-527"
|
||||
|
||||
|
||||
$SystemGroups = @(
|
||||
'Domain Admins', 'Domain Users', 'Domain Guests', 'Domain Computers',
|
||||
'Administrators', 'Users', 'Guests', 'Power Users', 'Backup Operators',
|
||||
'Replicator', 'Network Configuration Operators', 'Performance Monitor Users',
|
||||
'Performance Log Users', 'Distributed COM Users', 'IIS_IUSRS',
|
||||
'Cryptographic Operators', 'Event Log Readers', 'Certificate Service DCOM Access',
|
||||
'RDS Remote Access Servers', 'RDS Endpoint Servers', 'RDS Management Servers',
|
||||
'Hyper-V Administrators', 'Access Control Assistance Operators',
|
||||
'Remote Management Users', 'Storage Replica Administrators',
|
||||
'Schema Admins', 'Enterprise Admins', 'Cert Publishers', 'Domain Controllers',
|
||||
'Group Policy Creator Owners', 'RAS and IAS Servers', 'Server Operators',
|
||||
'Account Operators', 'Print Operators', 'Pre-Windows 2000 Compatible Access',
|
||||
'Incoming Forest Trust Builders', 'Windows Authorization Access Group',
|
||||
'Terminal Server License Servers', 'DHCP Users', 'DHCP Administrators',
|
||||
'DnsAdmins', 'DnsUpdateProxy', 'WINS Users', 'IIS_WPG',
|
||||
'Denied RODC Password Replication Group', 'Allowed RODC Password Replication Group',
|
||||
'Enterprise Read-only Domain Controllers', 'Read-only Domain Controllers',
|
||||
'Cloneable Domain Controllers', 'Protected Users', 'Key Admins',
|
||||
'Enterprise Key Admins'
|
||||
)
|
||||
27
Migration/user.ldif.orig
Normal file
27
Migration/user.ldif.orig
Normal file
@@ -0,0 +1,27 @@
|
||||
dn: CN=UGIVEN UNAME,CN=Users,DC=aipice,DC=local
|
||||
objectClass: top
|
||||
objectClass: person
|
||||
objectClass: organizationalPerson
|
||||
objectClass: user
|
||||
cn: UGIVEN UNAME
|
||||
sn: UNAME
|
||||
givenName: UGIVEN
|
||||
displayName: UGIVEN UNAME
|
||||
name: UGIVEN UNAME
|
||||
badPwdCount: 0
|
||||
codePage: 0
|
||||
countryCode: 0
|
||||
badPasswordTime: 0
|
||||
lastLogoff: 0
|
||||
lastLogon: 0
|
||||
objectSid: OBJECTSID
|
||||
accountExpires: 9223372036854775807
|
||||
logonCount: 0
|
||||
sAMAccountName: LOGIN
|
||||
userPrincipalName: LOGIN@aipice.local
|
||||
objectCategory: CN=Person,CN=Schema,CN=Configuration,DC=aipice,DC=local
|
||||
mail: LOGIN@hexa-h.com
|
||||
pwdLastSet: 134049268681752064
|
||||
userAccountControl: 512
|
||||
distinguishedName: CN=UGIVEN UNAME,CN=Users,DC=aipice,DC=local
|
||||
|
||||
Reference in New Issue
Block a user