PHP_AdminTool_Projekt/public/api/create_user.php
2025-12-17 16:06:10 +01:00

182 lines
5.6 KiB
PHP

<?php
declare(strict_types=1);
session_start();
// Load config
$config = require __DIR__ . '/../../config/config.php';
// Simple login check (same as index.php)
$sessionKey = $config['security']['session_key_user'] ?? 'admin_user';
if (!isset($_SESSION[$sessionKey])) {
header('Location: ../index.php?route=login');
exit;
}
// Only accept POST
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
header('Location: ../index.php?route=createuser');
exit;
}
// Basic input validation
$sam = trim((string)($_POST['samaccountname'] ?? ''));
$display = trim((string)($_POST['displayname'] ?? ''));
$mail = trim((string)($_POST['mail'] ?? ''));
$pass = (string)($_POST['password'] ?? '');
$ou = trim((string)($_POST['ou'] ?? ''));
$groups = trim((string)($_POST['groups'] ?? ''));
if ($sam === '' || $pass === '') {
$_SESSION['flash_error'] = 'Anmeldename und Passwort sind erforderlich.';
header('Location: ../index.php?route=createuser');
exit;
}
// Server-side password validation (same rules as CSV script)
$passwordHint = "Das Passwort muss mindestens 7 Zeichen lang sein, darf keine größeren Teile des Benutzernamens enthalten und muss Zeichen aus mindestens 3 von 4 Kategorien enthalten: Großbuchstaben, Kleinbuchstaben, Ziffern, Sonderzeichen.";
function validate_password_php(string $password, string $sam): array {
$errors = [];
if ($password === '' || mb_strlen($password) < 7) {
$errors[] = 'Passwort muss mindestens 7 Zeichen lang sein.';
}
$categories = 0;
if (preg_match('/[A-Z]/u', $password)) $categories++;
if (preg_match('/[a-z]/u', $password)) $categories++;
if (preg_match('/\d/', $password)) $categories++;
if (preg_match('/[^A-Za-z0-9]/u', $password)) $categories++;
if ($categories < 3) {
$errors[] = 'Passwort muss Zeichen aus mindestens 3 von 4 Kategorien enthalten.';
}
$samLower = mb_strtolower($sam);
$pwLower = mb_strtolower($password);
if ($samLower !== '' && mb_strpos($pwLower, $samLower) !== false) {
$errors[] = 'Passwort darf den Benutzernamen nicht enthalten.';
} else {
$minLen = 4;
if (mb_strlen($samLower) >= $minLen) {
$samLen = mb_strlen($samLower);
for ($len = $minLen; $len <= $samLen; $len++) {
for ($start = 0; $start <= $samLen - $len; $start++) {
$sub = mb_substr($samLower, $start, $len);
if (mb_strpos($pwLower, $sub) !== false) {
$errors[] = 'Passwort darf keine größeren Teile des Benutzernamens enthalten.';
break 2;
}
}
}
}
}
return $errors;
}
$pwErrors = validate_password_php($pass, $sam);
if (count($pwErrors) > 0) {
$_SESSION['flash_error'] = 'Ungültiges Passwort: ' . implode(' | ', $pwErrors) . "\n\nHinweis: $passwordHint";
header('Location: ../index.php?route=createuser');
exit;
}
if ($ou === '') {
$defaultOu = (string)($config['powershell']['default_ou'] ?? '');
if ($defaultOu !== '') {
$ou = $defaultOu;
}
}
// Build payload
$payload = [
'samaccountname' => $sam,
'displayname' => $display,
'mail' => $mail,
'password' => $pass,
'ou' => $ou,
'groups' => $groups,
'dry_run' => (bool)($config['powershell']['dry_run'] ?? false),
];
// Write payload to temp file
$tmpFile = tempnam(sys_get_temp_dir(), 'create_user_') . '.json';
file_put_contents($tmpFile, json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
// Build PS script path
$scriptDir = $config['powershell']['script_dir'] ?? __DIR__ . '/../../scripts/powershell';
$script = $scriptDir . DIRECTORY_SEPARATOR . 'create_user.ps1';
$exe = $config['powershell']['exe'] ?? 'powershell';
$executionPolicy = $config['powershell']['execution_policy'] ?? 'Bypass';
$cmd = sprintf(
'%s -NoProfile -NonInteractive -ExecutionPolicy %s -File "%s" -InputFile "%s"',
$exe,
$executionPolicy,
$script,
$tmpFile
);
// Execute and capture output and exit code
$output = [];
$returnVar = null;
if (!file_exists($script)) {
$_SESSION['flash_error'] = 'PowerShell-Skript nicht gefunden: ' . $script;
@unlink($tmpFile);
header('Location: ../index.php?route=createuser');
exit;
}
// Try to locate the PowerShell executable
$exePathCheck = shell_exec(sprintf('where %s 2>NUL', escapeshellarg($exe)));
if ($exePathCheck === null) {
// 'where' returns null when command fails; continue anyways, exec will fail if not found
}
exec($cmd . ' 2>&1', $output, $returnVar);
$json = implode("\n", $output);
// Optional: write raw output into logs for debugging
$ts = date('Y-m-d H:i:s');
$ctx = [
'cmd' => $cmd,
'return_code' => $returnVar,
'output' => $json,
];
$line = sprintf(
"[%s] %-7s %s %s%s",
$ts,
'DEBUG',
'PowerShell CMD',
json_encode($ctx, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
PHP_EOL
);
@file_put_contents(__DIR__ . '/../logs/create_user_output.log', $line, FILE_APPEND | LOCK_EX);
@unlink($tmpFile);
// Try to parse JSON output
$result = null;
if ($json !== '') {
$decoded = json_decode($json, true);
if (is_array($decoded)) {
$result = $decoded;
}
}
if ($result === null) {
$_SESSION['flash_error'] = 'Unbekannter Fehler beim Ausführen des PowerShell-Skripts: ' . ($json ?: 'Keine Ausgabe');
header('Location: ../index.php?route=createuser');
exit;
}
if (!empty($result['success'])) {
$_SESSION['flash_success'] = $result['message'] ?? 'Benutzer erfolgreich erstellt.';
} else {
$_SESSION['flash_error'] = $result['message'] ?? 'Fehler beim Erstellen des Benutzers.';
}
header('Location: ../index.php?route=createuser');
exit;