-
-
Save ZiTAL/e5671ea15892688d58ad9b7024b5163e to your computer and use it in GitHub Desktop.
php / laravel: ldap samaccountname
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
LDAP_DOMAIN="zital.lan" | |
LDAP_BASEDN="dc=zital,dc=lan" | |
LDAP_GROUPS='["Group01", "Group02"]' | |
LDAP_ATTRS='["*"]' | |
LDAP_HOSTS='["ldap01.zital.lan:389","ldap02.zital.lan:389","ldap02.zital.lan:389"]' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Models; | |
class Ldap | |
{ | |
private static $instance = NULL; | |
private static $options = | |
[ | |
LDAP_OPT_PROTOCOL_VERSION => 3, | |
LDAP_OPT_REFERRALS => 0 | |
]; | |
// .env | |
private static $domain = ''; | |
private static $basedn = ''; | |
private static $attributes = []; | |
private static $groups = []; | |
private static $hosts = []; | |
public static function setDefaults() | |
{ | |
self::$domain = env('LDAP_DOMAIN'); | |
self::$basedn = env('LDAP_BASEDN'); | |
self::$attributes = json_decode(env('LDAP_ATTRS')); | |
self::$groups = json_decode(env('LDAP_GROUPS')); | |
self::$hosts = json_decode(env('LDAP_HOSTS')); | |
} | |
public static function connect() | |
{ | |
self::setDefaults(); | |
$servers = self::$hosts; | |
$connection = false; | |
foreach ($servers as $server) | |
{ | |
$ldap = ldap_connect("ldap://{$server}"); | |
if ($ldap) | |
{ | |
foreach (self::$options as $key => $value) | |
ldap_set_option($ldap, $key, $value); | |
if (ldap_bind($ldap)) | |
{ | |
$connection = true; | |
break; | |
} | |
} | |
} | |
if ($connection) | |
{ | |
self::$instance = $ldap; | |
return true; | |
} | |
return false; | |
} | |
public static function getInstance() | |
{ | |
if (!self::$instance) | |
self::connect(); | |
return self::$instance; | |
} | |
public static function attempt($user, $passwd) | |
{ | |
$instance = self::getInstance(); | |
if ($instance) | |
{ | |
if (@ldap_bind($instance, $user . "@" . self::$domain, $passwd)) | |
{ | |
$dns = self::getDN($user); | |
if (isset($dns, $dns['dn']) && self::checkGroup($instance, $dns['dn'])) | |
return true; | |
} | |
} | |
return false; | |
} | |
public static function getDN($samaccountname) | |
{ | |
$instance = self::getInstance(); | |
$result = ldap_search($instance, self::$basedn, "(samaccountname={$samaccountname})", self::$attributes); | |
if ($result === FALSE) | |
return false; | |
$entries = ldap_get_entries($instance, $result); | |
if ($entries['count'] > 0) | |
return self::prepareEntry($entries[0]); | |
return false; | |
} | |
public static function checkGroup($ad, $userdn) | |
{ | |
$attributes = ['memberof']; | |
$result = ldap_read($ad, $userdn, '(memberof=*)', $attributes); | |
if ($result === false) | |
return false; | |
$entries = ldap_get_entries($ad, $result); | |
if ($entries['count'] > 0 && isset($entries[0], $entries[0]['memberof'], $entries[0]['memberof']['count'])) | |
{ | |
$count = $entries[0]['memberof']['count']; | |
for ($i = 0; $i < $count; $i++) | |
{ | |
$group = preg_match("/^CN=([^,]+)/", $entries[0]['memberof'][$i], $m); | |
if (isset($m) && isset($m[1])) | |
{ | |
$group = $m[1]; | |
if (in_array($group, self::$groups)) | |
return true; | |
} | |
} | |
} | |
return false; | |
} | |
private static function prepareEntry($entry) | |
{ | |
$result = []; | |
foreach ($entry as $key => $value) | |
{ | |
$type = gettype($value); | |
if ($type === 'string' && isset($entry[$value])) | |
{ | |
$key = $value; | |
$value = $entry[$value]; | |
unset($value['count']); | |
if (count($value) === 1) | |
$value = $value[0]; | |
} | |
// if is utf-8 | |
if (preg_match('//u', serialize($value))) | |
$result[$key] = $value; | |
} | |
return $result; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Http\Controllers; | |
use Illuminate\Http\Request; | |
use Illuminate\Support\Facades\Response; | |
use Illuminate\Support\Facades\Session; | |
use App\Models\Ldap as LdapM; | |
class LdapC extends Controller | |
{ | |
public function login(Request $request) | |
{ | |
try | |
{ | |
if(LdapM::attempt($request->user, $request->passwd)) | |
{ | |
$dn = LdapM::getDN($request->user); | |
Session::put('ldap', $dn); | |
return $dn; | |
} | |
else | |
return response()->json(['error' => 'Unauthorized'], 401); | |
} | |
catch(\Exception $e) | |
{ | |
return response()->json(['error' => $e->getMessage()], 500); | |
} | |
} | |
public function logout(Request $request) | |
{ | |
try | |
{ | |
Session::flush(); | |
} | |
catch(\Exception $e) | |
{ | |
return response()->json(['error' => $e->getMessage()], 500); | |
} | |
} | |
public function get(Request $request) | |
{ | |
try | |
{ | |
$s = Session::get('ldap'); | |
if($s) | |
return $s; | |
else | |
return response()->json(['error' => 'Unauthorized'], 401); | |
} | |
catch(\Exception $e) | |
{ | |
return response()->json(['error' => $e->getMessage()], 500); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment