Blueforce-Linux/scripts/identity/bf-reidentity
2026-09-17 13:22:26 +03:00

123 lines
4.8 KiB
Python
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""Atomically migrate a Blueforce device identity to a new dealer number."""
from __future__ import annotations
import os
import shutil
import subprocess
import sys
from pathlib import Path
IDENTITY_FILE = Path(os.environ.get("BF_IDENTITY_FILE", "/etc/blueforce/dealer-id"))
AUDIT_FILE = Path(os.environ.get("BF_IDENTITY_AUDIT", "/var/log/blueforce-identity.log"))
def run(*args: str) -> None:
subprocess.run(args, check=True, text=True, capture_output=True)
def valid(value: str) -> bool:
return len(value) == 8 and value.isdigit()
def audit(message: str) -> None:
AUDIT_FILE.parent.mkdir(parents=True, exist_ok=True)
with AUDIT_FILE.open("a", encoding="utf-8") as handle:
handle.write(message + "\n")
AUDIT_FILE.chmod(0o600)
def main() -> int:
if os.geteuid() != 0:
print("HATA: bayi kimliği geçişi için sudo bf gerekir.", file=sys.stderr)
return 3
if len(sys.argv) != 2 or not valid(sys.argv[1]):
print("Kullanım: sudo bf-reidentity YYYYYYYY", file=sys.stderr)
return 2
new_id = sys.argv[1]
try:
old_id = IDENTITY_FILE.read_text(encoding="utf-8").strip()
except OSError as exc:
print(f"HATA: mevcut bayi kimliği okunamadı: {exc}", file=sys.stderr)
return 1
if not valid(old_id) or old_id == new_id:
print("HATA: yeni kimlik mevcut kimlikten farklı ve 8 haneli olmalıdır.", file=sys.stderr)
return 2
old_user = f"bf-{old_id}"
new_user = f"bf-{new_id}"
if subprocess.run(("id", "-u", new_user), capture_output=True).returncode == 0:
print(f"HATA: hedef kullanıcı zaten var: {new_user}", file=sys.stderr)
return 1
if subprocess.run(("id", "-u", old_user), capture_output=True).returncode != 0:
print(f"HATA: mevcut kullanıcı bulunamadı: {old_user}", file=sys.stderr)
return 1
old_group = old_user
old_home = Path(f"/home/{old_user}")
new_home = Path(f"/home/{new_user}")
old_hostname = subprocess.run(("hostname",), check=True, capture_output=True, text=True).stdout.strip()
renamed = False
group_renamed = False
moved_sudo = moved_ssh = False
new_sudo = Path(f"/etc/sudoers.d/{new_user}")
old_sudo = Path(f"/etc/sudoers.d/{old_user}")
new_ssh = Path(f"/etc/ssh/sshd_config.d/99-{new_user}.conf")
old_ssh = Path(f"/etc/ssh/sshd_config.d/99-{old_user}.conf")
try:
audit(f"identity-change requested old={old_id} new={new_id}")
run("usermod", "-l", new_user, old_user)
renamed = True
if subprocess.run(("getent", "group", old_group), capture_output=True).returncode == 0:
run("groupmod", "-n", new_user, old_group)
group_renamed = True
run("usermod", "-d", f"/home/{new_user}", "-m", new_user)
if old_sudo.exists():
shutil.move(old_sudo, new_sudo)
moved_sudo = True
text = new_sudo.read_text(encoding="utf-8").replace(old_user, new_user)
new_sudo.write_text(text, encoding="utf-8")
run("visudo", "-cf", str(new_sudo))
if old_ssh.exists():
shutil.move(old_ssh, new_ssh)
moved_ssh = True
text = new_ssh.read_text(encoding="utf-8").replace(f"AllowUsers {old_user}", f"AllowUsers {new_user}")
new_ssh.write_text(text, encoding="utf-8")
run("sshd", "-t")
tmp = IDENTITY_FILE.with_suffix(".tmp")
tmp.write_text(new_id + "\n", encoding="utf-8")
tmp.chmod(0o600)
os.replace(tmp, IDENTITY_FILE)
run("hostnamectl", "set-hostname", new_user)
audit(f"identity-change completed old={old_id} new={new_id} user={new_user}")
print(f"OK: {old_id} -> {new_id} ({new_user})")
return 0
except Exception as exc:
try:
if IDENTITY_FILE.read_text(encoding="utf-8").strip() == new_id:
IDENTITY_FILE.write_text(old_id + "\n", encoding="utf-8")
IDENTITY_FILE.chmod(0o600)
if moved_ssh and new_ssh.exists():
shutil.move(new_ssh, old_ssh)
if moved_sudo and new_sudo.exists():
shutil.move(new_sudo, old_sudo)
if renamed:
run("usermod", "-d", str(old_home), "-m", new_user)
if group_renamed:
run("groupmod", "-n", old_group, new_user)
if renamed:
run("usermod", "-l", old_user, new_user)
if old_hostname:
run("hostnamectl", "set-hostname", old_hostname)
except Exception:
pass
audit(f"identity-change failed old={old_id} new={new_id}: {exc}")
print(f"HATA: kimlik geçişi geri alınmaya çalışıldı: {exc}", file=sys.stderr)
return 1
if __name__ == "__main__":
raise SystemExit(main())