I have a process in lumen project (Laravel 6.2) where a user is identified through an LDAP.
The code looks like this:
<?php
namespace App\Http\Helpers;
// Currently unused
// use App\User;
// use Firebase\JWT\JWT;
use Illuminate\Support\Facades\Log;
class LDAP
{
private $connection, $password;
protected $domain, $username, $ldap_address, $ldap_port;
/**
* Constructs the ldap connector with data used for the connection and
* bind process.
*/
function __construct()
{
$this->domain = env("LDAP_DOMAIN");
$this->username = env("LDAP_USERNAME");
$this->password = env("LDAP_PASSWORD");
$this->ldap_address = env("LDAP_ADDRESS");
$this->ldap_port = env("LDAP_PORT");
}
/**
* Establishes a connection to the ldap server and saves it in
* #var Resource $connection.
*
* #return true
* On success
* #return false
* On failure
*/
private function connect()
{
$this->connection = ldap_connect($this->ldap_address, $this->ldap_port);
if($this->connection)
{
Log::info("Connection established");
ldap_set_option($this->connection, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($this->connection, LDAP_OPT_REFERRALS, 0);
$bind = ldap_bind($this->connection, $this->domain . "\\" . $this->username, $this->password);
if($bind)
{
Log::info("Bind valid");
return true;
}
else
{
Log::info("Bind failed");
return false;
}
}
else
{
Log::info("Connection failed");
return false;
}
}
private function disconnect()
{
ldap_unbind($this->connection);
}
/**
* Searches for a specific person in the LDAP-Directory and returns important
* data from this person which will be used later in the application.
*
* #param String $person
* The person to search for
* #return Array $result
* The persons data
*/
public function getUser($username, $password)
{
try
{
$is_connected = $this->connect();
if(!$is_connected)
{
$this->disconnect();
return false;
}
$dn = "OU=Benutzer,OU=sdfsfd,DC=sfdsfsf,DC=de";
$fields = "(|(samaccountname=*$username*))";
$search = ldap_search($this->connection, $dn, $fields);
$result = ldap_get_entries($this->connection, $search);
if($result)
{
$bind = ldap_bind($this->connection, $this->domain . "\\" . $username, $password);
if($bind && strlen($password) > 0)
{
return mb_convert_encoding($result, 'UTF-8');
}
else
{
return "Invalid credentials!";
}
}
else
{
return "User does not exist!";
}
}
catch(\Exception $e)
{
$errno = ldap_errno($this->connection);
if ($errno) {
$ret = array("ldap_error" => $errno, "message" => ldap_err2str($errno));
}else{
$ret = array("exception_code" => $e->getCode(), "message" => $e->getMessage());
}
return $ret;
}
finally
{
$this->disconnect();
}
}
}
Now, we faced some issues when handling errors from the ldap_bind().
The error code thrown by the ldap functions couldnt be evaluated by Lumen, so we had to catch them and evaluate it manually through the ldap_errno functionality.
What puzzles me is that the $this->connection is passed to the ldap_errno() function. Why isnt it the $bind?
After all, its the bind which failed, not the connect. AFAIK the ldap_connect() doesnt even establish a connection, but instead verifies whether the credentials are plausible.
However, it works ^^ But why? What is happening in ldap_errno that the connection is passed to it, not the bind?
Because ldap_connect returns an internal handle that is identifying the "connection". ldap_errno and ldap_error then return information regarding the last error on that "connection".
So when you call them after an ldap_bind (which returns true or false depending on the outcome) you need the connection that this happened on, not the result of the bind.
Please note that "connection" does not necessarily mean that the connection to the server has already been established.
Related
I'm doing websocket server to game and i have problem to stash information about users. I write event listener which run special event according to first incoming packet in message. Everything works OK but i don't have idea how stash the data about clients...
I'm try to use session but all time, my variables not stored in session.
Command to run server ( i'm try memcache and PDOSession storage ):
<?php
/**
* {#inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$output->writeln('Server starting');
$communication = $this->getContainer()->get('uo_server.server_communication');
$pdo = new \PDO('mysql:host=127.0.01;dbname=uo-session', 'root', null);
$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
$dbOptions = array(
'db_table' => 'sessions',
'db_id_col' => 'sess_id',
'db_data_col' => 'sess_data',
'db_time_col' => 'sess_time',
'db_lifetime_col' => 'sess_lifetime',
'lock_mode' => 0
);
$sessionProvider = new PdoSessionHandler($pdo, $dbOptions);
$server = IoServer::factory(
new SessionProvider($communication, $sessionProvider),
2593,
'127.0.0.1');
$server->run();
}
Message component looks like:
function __construct(ContainerInterface $container)
{
$this->container = $container;
$this->packetDispatcher = $container->get('uo_server.packets_event_dispatcher');
$this->connections = new ArrayCollection();
}
/**
* When a new connection is opened it will be passed to this method
* #param ConnectionInterface $conn The socket/connection that just connected to your application
* #throws \Exception
*/
function onOpen(ConnectionInterface $conn)
{
$this->connections->add($conn);
/**
* #var Session $session
*/
$session = $conn->Session;
$session->setId('session_'.$conn->resourceId);
$session->start();
}
/**
* This is called before or after a socket is closed (depends on how it's closed). SendMessage to $conn will not result in an error if it has already been closed.
* #param ConnectionInterface $conn The socket/connection that is closing/closed
* #throws \Exception
*/
function onClose(ConnectionInterface $conn)
{
$conn->Session->save();
if($this->connections->contains($conn)) {
$this->connections->removeElement($conn);
}
}
/**
* If there is an error with one of the sockets, or somewhere in the application where an Exception is thrown,
* the Exception is sent back down the stack, handled by the Server and bubbled back up the application through this method
* #param ConnectionInterface $conn
* #param \Exception $e
* #throws \Exception
*/
function onError(ConnectionInterface $conn, \Exception $e)
{
$conn->Session->save();
// TODO: Implement onError() method.
}
/**
* Triggered when a client sends data through the socket
* #param \Ratchet\ConnectionInterface $from The socket/connection that sent the message to your application
* #param string $msg The message received
* #throws \Exception
*/
function onMessage(ConnectionInterface $conn, $msg)
{
$this->packetDispatcher->dispatchEvent($conn, $msg);
$conn->Session->save();
}
Packet dispatcher is simply:
public function dispatchEvent(ConnectionInterface $sender, $msg)
{
$data = unpack('C*',$msg);
$eventPacket = "0x".DataConverter::convertDecimalToHex($data[1]);
$event = isset($this->packetsEvents[$eventPacket]) ? $this->packetsEvents[$eventPacket] : null;
if ($event !== null) {
$incomingEvent = new MainEvent($sender, $msg);
if ($this->dispatcher->hasListeners($event)) {
$this->dispatcher->dispatch($event, $incomingEvent);
} else {
Logger::Log('Event :'.$event.' is not implement yet!');
}
}
}
at least the example login event:
public function onLogin(MainEvent $event)
{
$this->event = $event;
$packetReader = new PacketReader($this->event->getMessage());
$login = $packetReader->getByteFrom(2, 30);
$password = $packetReader->getByteFrom(32, 30); //todo some byte on the end?
if($this->accountFinder->checkAccountAccess($login, $password)) {
Logger::Log('try to log:'.$login . '/' . $password.';');
$account = $this->accountFinder->getAccount($login, $password);
return $this->loginSuccess($account);
}
if($this->serverInfo['auto_account'] && $this->accountFinder->checkAccountExist($login) === false) {
Logger::Log('account not found, but autoaccounting is on. Account created;');
$account = $this->accountFinder->createUser($login, $password);
return $this->loginSuccess($account);
}
Logger::Log('login for credientals: '.$login.'/'.$password.' failure;');
$this->loginFailure($login);
}
private function loginSuccess(Account $account)
{
$ip = explode(".", $this->serverInfo['host']);
$packet = new Packet;
$packet
->prependPacket("A8")
->appendPacket("FF")
->appendPacket(DataConverter::convertDecimalToHex(1), 4)
->appendPacket(DataConverter::convertDecimalToHex(1), 4)
->appendPacket(DataConverter::convertStringToHex($this->serverInfo['name']), 64, Packet::PAD_FROM_RIGHT)
->appendPacket(DataConverter::convertDecimalToHex($this->serverInfo['full']), 2) //todo full is not from PARAM!!!
->appendPacket(DataConverter::convertDecimalToHex($this->serverInfo['timezone']), 2);
for ($i=3; $i>=0; $i--) {
$packet->appendPacket(DataConverter::convertDecimalToHex($ip[$i]), 2);
}
$currentLenght = $packet->getPacketSize();
$packet->injectPacket(DataConverter::convertDecimalToHex($currentLenght + 2), 4, 2);
$this->event->setToSession('accountId', $account->getId());
$this->event->getClientSession()->save();
$this->event->getClient()->send($packet->getPacket());
return true;
}
/**
* TODO FAILURE FROM BANS ETC.
* #return bool
*/
private function loginFailure($login)
{
$reason = 0;
if ($this->accountFinder->checkAccountExist($login)) {
$reason = 3;
}
$packet = new Packet;
$packet
->prependPacket("82")
->appendPacket(DataConverter::convertDecimalToHex($reason), 2);
$this->event->getClient()->send($packet->getPacket());
return true;
}
When i try to read the session in next event, it's not exist. Looks like new session start, but files and session in database not exist (its not created). It's possible to storage data like this ? If not, what alternatives i had?
link to repo with full code:
REPO
May wabsite has faced max_user_connections error
After contacting the website hosting provider they said I have to close the connection immediately after accessing the database using mysql_close()
My question is that how I can close the connection if my php file is :
*/
if (!defined('QA_VERSION')) { // don't allow this page to be requested directly from browser
header('Location: ../');
exit;
}
/**
* Indicates to the Q2A database layer that database connections are permitted fro this point forwards
* (before this point, some plugins may not have had a chance to override some database access functions).
*/
function qa_db_allow_connect()
{
if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); }
global $qa_db_allow_connect;
$qa_db_allow_connect=true;
}
/**
* Connect to the Q2A database, select the right database, optionally install the $failhandler (and call it if necessary).
* Uses mysqli as of Q2A 1.7.
*/
function qa_db_connect($failhandler=null)
{
if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); }
global $qa_db_connection, $qa_db_fail_handler, $qa_db_allow_connect;
if (!$qa_db_allow_connect)
qa_fatal_error('It appears that a plugin is trying to access the database, but this is not allowed until Q2A initialization is complete.');
if (isset($failhandler))
$qa_db_fail_handler = $failhandler; // set this even if connection already opened
if ($qa_db_connection instanceof mysqli)
return;
// in mysqli we connect and select database in constructor
if (QA_PERSISTENT_CONN_DB)
$db = new mysqli('p:'.QA_FINAL_MYSQL_HOSTNAME, QA_FINAL_MYSQL_USERNAME, QA_FINAL_MYSQL_PASSWORD, QA_FINAL_MYSQL_DATABASE);
else
$db = new mysqli(QA_FINAL_MYSQL_HOSTNAME, QA_FINAL_MYSQL_USERNAME, QA_FINAL_MYSQL_PASSWORD, QA_FINAL_MYSQL_DATABASE);
// must use procedural `mysqli_connect_error` here prior to 5.2.9
$conn_error = mysqli_connect_error();
if ($conn_error)
qa_db_fail_error('connect', $db->connect_errno, $conn_error);
// From Q2A 1.5, we explicitly set the character encoding of the MySQL connection, instead of using lots of "SELECT BINARY col"-style queries.
// Testing showed that overhead is minimal, so this seems worth trading off against the benefit of more straightforward queries, especially
// for plugin developers.
if (!$db->set_charset('utf8'))
qa_db_fail_error('set_charset', $db->errno, $db->error);
qa_report_process_stage('db_connected');
$qa_db_connection=$db;
}
/**
* If a DB error occurs, call the installed fail handler (if any) otherwise report error and exit immediately.
*/
function qa_db_fail_error($type, $errno=null, $error=null, $query=null)
{
if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); }
global $qa_db_fail_handler;
#error_log('PHP Question2Answer MySQL '.$type.' error '.$errno.': '.$error.(isset($query) ? (' - Query: '.$query) : ''));
if (function_exists($qa_db_fail_handler))
$qa_db_fail_handler($type, $errno, $error, $query);
else {
echo '<hr><font color="red">Database '.htmlspecialchars($type.' error '.$errno).'<p>'.nl2br(htmlspecialchars($error."\n\n".$query));
qa_exit('error');
}
}
/**
* Return the current connection to the Q2A database, connecting if necessary and $connect is true.
*/
function qa_db_connection($connect=true)
{
if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); }
global $qa_db_connection;
if ($connect && !($qa_db_connection instanceof mysqli)) {
qa_db_connect();
if (!($qa_db_connection instanceof mysqli))
qa_fatal_error('Failed to connect to database');
}
return $qa_db_connection;
}
/**
* Disconnect from the Q2A database.
*/
function qa_db_disconnect()
{
if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); }
global $qa_db_connection;
if ($qa_db_connection instanceof mysqli) {
qa_report_process_stage('db_disconnect');
if (!QA_PERSISTENT_CONN_DB) {
if (!$qa_db_connection->close())
qa_fatal_error('Database disconnect failed');
}
$qa_db_connection=null;
}
}
/**
* Run the raw $query, call the global failure handler if necessary, otherwise return the result resource.
* If appropriate, also track the resources used by database queries, and the queries themselves, for performance debugging.
*/
function qa_db_query_raw($query)
{
if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); }
if (QA_DEBUG_PERFORMANCE) {
global $qa_usage;
// time the query
$oldtime = array_sum(explode(' ', microtime()));
$result = qa_db_query_execute($query);
$usedtime = array_sum(explode(' ', microtime())) - $oldtime;
// fetch counts
$gotrows = $gotcolumns = null;
if ($result instanceof mysqli_result) {
$gotrows = $result->num_rows;
$gotcolumns = $result->field_count;
}
$qa_usage->logDatabaseQuery($query, $usedtime, $gotrows, $gotcolumns);
}
else
$result = qa_db_query_execute($query);
// #error_log('Question2Answer MySQL query: '.$query);
if ($result === false) {
$db = qa_db_connection();
qa_db_fail_error('query', $db->errno, $db->error, $query);
}
return $result;
}
/**
* Lower-level function to execute a query, which automatically retries if there is a MySQL deadlock error.
*/
function qa_db_query_execute($query)
{
if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); }
$db = qa_db_connection();
for ($attempt = 0; $attempt < 100; $attempt++) {
$result = $db->query($query);
if ($result === false && $db->errno == 1213)
usleep(10000); // deal with InnoDB deadlock errors by waiting 0.01s then retrying
else
break;
}
return $result;
}
/**
* Return $string escaped for use in queries to the Q2A database (to which a connection must have been made).
*/
function qa_db_escape_string($string)
{
if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); }
$db = qa_db_connection();
return $db->real_escape_string($string);
}
/**
* Return $argument escaped for MySQL. Add quotes around it if $alwaysquote is true or it's not numeric.
* If $argument is an array, return a comma-separated list of escaped elements, with or without $arraybrackets.
*/
function qa_db_argument_to_mysql($argument, $alwaysquote, $arraybrackets=false)
{
if (is_array($argument)) {
$parts=array();
foreach ($argument as $subargument)
$parts[] = qa_db_argument_to_mysql($subargument, $alwaysquote, true);
if ($arraybrackets)
$result = '('.implode(',', $parts).')';
else
$result = implode(',', $parts);
}
elseif (isset($argument)) {
if ($alwaysquote || !is_numeric($argument))
$result = "'".qa_db_escape_string($argument)."'";
else
$result = qa_db_escape_string($argument);
}
else
$result = 'NULL';
return $result;
}
/**
* Return the full name (with prefix) of database table $rawname, usually if it used after a ^ symbol.
*/
function qa_db_add_table_prefix($rawname)
{
if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); }
$prefix = QA_MYSQL_TABLE_PREFIX;
if (defined('QA_MYSQL_USERS_PREFIX')) {
switch (strtolower($rawname)) {
case 'users':
case 'userlogins':
case 'userprofile':
case 'userfields':
case 'messages':
case 'cookies':
case 'blobs':
case 'cache':
case 'userlogins_ibfk_1': // also special cases for constraint names
case 'userprofile_ibfk_1':
$prefix = QA_MYSQL_USERS_PREFIX;
break;
}
}
return $prefix.$rawname;
}
/**
* Callback function to add table prefixes, as used in qa_db_apply_sub().
*/
function qa_db_prefix_callback($matches)
{
return qa_db_add_table_prefix($matches[1]);
}
/**
* Substitute ^, $ and # symbols in $query. ^ symbols are replaced with the table prefix set in qa-config.php.
* $ and # symbols are replaced in order by the corresponding element in $arguments (if the element is an array,
* it is converted recursively into comma-separated list). Each element in $arguments is escaped.
* $ is replaced by the argument in quotes (even if it's a number), # only adds quotes if the argument is non-numeric.
* It's important to use $ when matching a textual column since MySQL won't use indexes to compare text against numbers.
*/
function qa_db_apply_sub($query, $arguments)
{
$query = preg_replace_callback('/\^([A-Za-z_0-9]+)/', 'qa_db_prefix_callback', $query);
if (!is_array($arguments))
return $query;
$countargs = count($arguments);
$offset = 0;
for ($argument = 0; $argument < $countargs; $argument++) {
$stringpos = strpos($query, '$', $offset);
$numberpos = strpos($query, '#', $offset);
if ($stringpos === false || ($numberpos !== false && $numberpos < $stringpos)) {
$alwaysquote = false;
$position = $numberpos;
}
else {
$alwaysquote = true;
$position = $stringpos;
}
if (!is_numeric($position))
qa_fatal_error('Insufficient parameters in query: '.$query);
$value = qa_db_argument_to_mysql($arguments[$argument], $alwaysquote);
$query = substr_replace($query, $value, $position, 1);
$offset = $position + strlen($value); // allows inserting strings which contain #/$ character
}
return $query;
}
/**
* Run $query after substituting ^, # and $ symbols, and return the result resource (or call fail handler).
*/
function qa_db_query_sub($query) // arguments for substitution retrieved using func_get_args()
{
$funcargs=func_get_args();
return qa_db_query_raw(qa_db_apply_sub($query, array_slice($funcargs, 1)));
}
/**
* Return the number of rows in $result. (Simple wrapper for mysqli_result::num_rows.)
*/
function qa_db_num_rows($result)
{
if ($result instanceof mysqli_result)
return $result->num_rows;
return 0;
}
/**
* Return the value of the auto-increment column for the last inserted row.
*/
function qa_db_last_insert_id()
{
$db = qa_db_connection();
return $db->insert_id;
}
/**
* Return the number of rows affected by the last query.
*/
function qa_db_affected_rows()
{
$db = qa_db_connection();
return $db->affected_rows;
}
/**
* For the previous INSERT ... ON DUPLICATE KEY UPDATE query, return whether an insert operation took place.
*/
function qa_db_insert_on_duplicate_inserted()
{
return (qa_db_affected_rows() == 1);
}
/**
* Return a random integer (as a string) for use in a BIGINT column.
* Actual limit is 18,446,744,073,709,551,615 - we aim for 18,446,743,999,999,999,999.
*/
function qa_db_random_bigint()
{
return sprintf('%d%06d%06d', mt_rand(1, 18446743), mt_rand(0, 999999), mt_rand(0, 999999));
}
/**
* Return an array of the names of all tables in the Q2A database, converted to lower case.
* No longer used by Q2A and shouldn't be needed.
*/
function qa_db_list_tables_lc()
{
return array_map('strtolower', qa_db_list_tables());
}
/**
* Return an array of the names of all tables in the Q2A database.
*/
function qa_db_list_tables()
{
return qa_db_read_all_values(qa_db_query_raw('SHOW TABLES'));
}
/*
The selectspec array can contain the elements below. See qa-db-selects.php for lots of examples.
I bet you have your code set to use persistent connections for MySQL. This can result in open but idle connections, maxing out whatever your (most likely shared) hosting provider allocates for you.
You have a QA_PERSISTENT_CONN_DB constant in your code that determines your connection mode. You will find it defined as true or false somewhere in a configuration file. (It's not defined in your code above). Ensure it is set to false and see if the problem is resolved. When persistent connections are off, the code above takes care of closing the connections. You don't need to add it in.
If you're interested in knowing more about persistent connections, this answer covers a lot of ground; and there's more in the manual:
Persistent connections are links that do not close when the execution of your script ends.
Next time, make sure you read through your code to see if the functionality is already there (in this case, it's inside function qa_db_disconnect()), and if it's simply a matter of configuration.
I have the following script that is not returning any thing at all, the best I've gotten is a var_dump to say bool(false).. There is nothing at all in my error_log and no exceptions are being thrown:
index.php:
require("php/bootstrap.php");
$campaign = new Campaign($_GET['campaign'], $mysql);
bootstrap.php:
define ("MYSQL_USER", "specialagent");
define ("MYSQL_PASS", "supertopsecret");
define ("MYSQL_HOST", "127.0.0.1");
define ("MYSQL_PORT", "3306");
define ("MYSQL_DB", "databasewithsecretinformation");
/* Auto include classes on instantiation */
function __autoload($class_name) {
include 'classes/'.$class_name.'.php';
}
/* Connections */
try {
$mysql = new PDO("mysql:host=".MYSQL_HOST.";dbname=test", MYSQL_USER, MYSQL_PASS);
} catch(PDOException $e) {
die("There was a problem connecting to the database. Error: " . $e->getMessage());
}
Campaign.php
class Campaign {
protected $dbh;
private $campaign_id = "";
private $name = "";
public function __construct ($campaign_id, PDO $db) {
//if ($campaign_id) {
$this->setCampaignID($campaign_id);
$this->dbh = $db;
$this->loadCampaignInfo();
//}
}
public function getCampaignID() {
return $this->campaign_id;
}
public function setCampaignID($id) {
$this->campaign_id = $id;
}
public function __destruct() {
//$this->dbh = null;
}
public function loadCampaignInfo() {
/* Get info from database */
$sql = "SELECT * FROM campaigns WHERE campaign=:campaignID";
try {
echo "trying query...$sql<br />";
if ($this->dbh instanceof PDO) {
$stmt = $this->dbh->prepare($sql);
$stmt->bindParam(":campaignID", $this->campaign_id, PDO::PARAM_STR);
$stmt->execute();
$row = $stmt->fetch();
echo "Returned Data: ";
var_dump($row);
} else {
echo "Not a valid PDO resource";
}
} catch (PDOException $e) {
echo "Problem : " . $e->getMessage;
} catch (Exception $e) {
echo "Other problem : " . $e->getMessage;
}
/* Set properties */
}
}
Output:
trying query...SELECT * FROM campaigns WHERE campaign=:campaignID
Returned Data: bool(false)
The problem has nothing to do with PDO.
Returned Data: bool(false) means no row were found to match condition.
Check your table if it contain the data and check input as well.
Check if you are getting the right class from autoload and all the stuff like that.
Also, change your bootstrap connection to
ini_set('display_errors',1);
error_reporting(E_ALL);
/* Connections */
$mysql = new PDO("mysql:host=".MYSQL_HOST.";dbname=test", MYSQL_USER, MYSQL_PASS);
$mysql->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
you may wish also to make the method less bloated too:
/* Get info from database */
public function loadCampaignInfo()
{
$sql = "SELECT * FROM campaigns WHERE campaign=?";
$stmt = $this->dbh->prepare($sql);
$stmt->execute([$this->campaign_id]);
return $stmt->fetch();
}
The problem was that the user did not have the correct privileges to access the database, after Your Common Sense suggested the creds were the issue, logged into MySQL cli and noticed the database was not in SHOW DATABASES.
Thanks for the help everybody.
I'm newbie to Laravel and even Frameworks... I've tried some basic authentication in Laravel. Now here's my problem. I've got an LDAP login script in conventional PHP and I want to switch to Laravel LDAP login. Can anyone help me with the code/bundle or anything? I'll be very grateful for this help.
function check_login($username,$password){
if($username=="" || $password=="")
return 1 ;
$server1="ldap.xyz.com"; //server1 ip or dns
$server2="ldap.xyz.com"; //server2 ip or dns
$firstqry=array("alias,sn,givenname,mail,dn");
$secqry=array("givenname,jobtitledescription,sn,alias,mail,l,employeenumber");
$firstfilter="(alias=$username)";
$searchin="o=XYZ,c=AN";
$ldap=ldap_connect($server1,389);
if (!($res = #ldap_bind($ldap))) {
//echo "<b>Cannt Contact Server 1 :" .$server1 .", Now Contacting Server 2 :".$server2. ".....</b><br>";
$laststatus=ldap_errno($ldap);
if($laststatus==81){
$ldap=ldap_connect($server2,389);
if (!($res = #ldap_bind($ldap))) {
//echo "<b>Cannt Contact Server 2 :" .$server2 ."...</B><br>";
$laststatus=ldap_errno($ldap);
if($laststatus==81){
//echo "<b>Please Contact The Network Adminstartion!!</b><br>";
return 2 ; // server not found
}
}else{
$laststatus=ldap_errno($ldap);
}
}
}else{
$laststatus=ldap_errno($ldap);
}
//echo "Connection :" .ldap_error($ldap)."<br>";
if($laststatus==0){
$sr=ldap_search($ldap,$searchin,$firstfilter,$firstqry);
$info = ldap_get_entries($ldap, $sr);
for ($i=0; $i<$info["count"]; $i++) {
$searchdn=$info[$i]["dn"];
$searchalias=$info[$i]["alias"][0];
}
if($searchdn){
$secfilter=$firstfilter;
$sr2=ldap_search($ldap,$searchin,$secfilter);
$info2 = ldap_get_entries($ldap, $sr2);
$i=0;
if(count($info2)){
if (!($res = #ldap_bind($ldap,$searchdn,addslashes($password)))) {
return 1 ;
}else{
ldap_close($ldap);
return 0 ;
}
}
}else{
return 1 ;
}
}
}
If you are on L4 you might try this bundle https://github.com/wells/l4-ldap-ntlm.
I've resolved the issue by extending the Auth class this way.
use Illuminate\Hashing\HasherInterface,
Illuminate\Auth\UserInterface,
Illuminate\Auth\UserProviderInterface;
class XyzUserProvider implements UserProviderInterface {
/**
* The hasher implementation.
*
* #var \Illuminate\Hashing\HasherInterface
*/
protected $hasher;
/**
* The Eloquent user model.
*
* #var string
*/
protected $model;
/**
* Retrieve a user by their unique identifier.
*
* #param mixed $identifier
* #return \Illuminate\Auth\UserInterface|null
*/
public function retrieveById($identifier)
{
$user = new UserModel;
return $user->newQuery()->find($identifier);
}
/**
* Retrieve a user by the given credentials.
*
* #param array $credentials
* #return \Illuminate\Auth\UserInterface|null
*/
public function retrieveByCredentials(array $credentials)
{
// First we will add each credential element to the query as a where clause.
// Then we can execute the query and, if we found a user, return it in a
// Eloquent User "model" that will be utilized by the Guard instances.
$user = new UserModel;
$query = $user->newQuery();
foreach ($credentials as $key => $value)
{
if ( ! str_contains($key, 'password')) $query->where($key, $value);
}
return $query->first();
}
/**
* Validate a user against the given credentials.
*
* #param \Illuminate\Auth\UserInterface $user
* #param array $credentials
* #return bool
*/
public function validateCredentials(UserInterface $user, array $credentials)
{
$login_attempt = $this->validateLogin($credentials['username'],$credentials['password']);
if($login_attempt == 0)
return true;
else
return false;
}
public function validateLogin($username,$password)
{
if($username=="" || $password=="")
return 1 ;
$server1="ldap.xyz.com"; //server1 ip or dns
$server2="ldap.xyz.com"; //server2 ip or dns
$firstqry=array("alias,sn,givenname,mail,dn");
$secqry=array("givenname,jobtitledescription,sn,alias,mail,l,employeenumber");
$firstfilter="(alias=$username)";
$searchin="o=XYZ,c=AN";
$ldap=ldap_connect($server1,389);
if (!($res = #ldap_bind($ldap))) {
//echo "<b>Cannt Contact Server 1 :" .$server1 .", Now Contacting Server 2 :".$server2. ".....</b><br>";
$laststatus=ldap_errno($ldap);
if($laststatus==81){
$ldap=ldap_connect($server2,389);
if (!($res = #ldap_bind($ldap))) {
//echo "<b>Cannt Contact Server 2 :" .$server2 ."...</B><br>";
$laststatus=ldap_errno($ldap);
if($laststatus==81){
//echo "<b>Please Contact The Network Adminstartion!!</b><br>";
return 2 ; // server not found
}
}else{
$laststatus=ldap_errno($ldap);
}
}
}else{
$laststatus=ldap_errno($ldap);
}
//echo "Connection :" .ldap_error($ldap)."<br>";
if($laststatus==0){
$sr=ldap_search($ldap,$searchin,$firstfilter,$firstqry);
$info = ldap_get_entries($ldap, $sr);
for ($i=0; $i<$info["count"]; $i++) {
$searchdn=$info[$i]["dn"];
$searchalias=$info[$i]["alias"][0];
}
if($searchdn){
$secfilter=$firstfilter;
$sr2=ldap_search($ldap,$searchin,$secfilter);
$info2 = ldap_get_entries($ldap, $sr2);
$i=0;
if(count($info2)){
if (!($res = #ldap_bind($ldap,$searchdn,addslashes($password)))) {
return 1 ;
}else{
ldap_close($ldap);
return 0 ;
}
}
}else{
return 1 ;
}
}
}
}
I have a couple services that id like to have access to from a website. Like maybe a simple website with login for users and access to start|Stop|Restart services if they are down.
IDK if this is possible within a webpage as im not all that experienced yet.
From a shell i can just type out service b3-2 start and the service will start. now i just want to be able todo that from within a webpage where the start|Stop|Restart are buttons and there's a info/status area and an output box below everything to show errors if any.
If anyone can help me with this that would be awesome. Mostly my questions are-
Is it possible to do this from a webpage?
If so how hard will it be to create?
What else can you tell me to better help me with this?
on a side note il be using this for mostly only my B3 services(Big Brother Bot).
I wrote long time ago an 'Eggdrop Webinterface' in PHP with http://de.php.net/manual/en/book.ssh2.php Module.
You can connect with this module via SSH to your linux server and submit shell commands. In my Webinterface I wrote an Shellscript that do all the jobs (Add / remove / start / stop and so on) and executed over php ssh2 module.
<?php
class ssh
{
private $sql;
private $con;
private static $instance;
public static function getInstance()
{
if (!self::$instance)
{
self::$instance = new ssh();
}
return self::$instance;
}
function __construct()
{
$this->sql = sql::getInstance();
}
/* Verbindung über SSH aufnehmen */
public function connect ($rootid)
{
global $cfg;
$q = $this->sql->query("SELECT ROOT_SSH_IP, ROOT_SSH_USER, ROOT_SSH_PASS, ROOT_SSH_PORT FROM ".prfx."rootserver WHERE ROOT_ID = '".$rootid."'");
$r = $this->sql->content($q);
$blowfish = new Blowfish($cfg["BLOWFISHKEY"]);
$pass = $blowfish->Decrypt($r["ROOT_SSH_PASS"]);
$this->ssh_connect($r["ROOT_SSH_IP"], $r["ROOT_SSH_PORT"], $pass, $r["ROOT_SSH_USER"]);
return true;
}
/* Disconnect */
public function my_ssh_disconnect($reason, $message, $language) {
printf("Server disconnected with reason code [%d] and message: %s\n",
$reason, $message);
return true;
}
/* Eigentliche ssh_connect Funktion */
public function ssh_connect($host, $port, $pass, $user="root")
{
$methods = array(
'kex' => 'diffie-hellman-group1-sha1',
'client_to_server' => array(
'crypt' => '3des-cbc',
'comp' => 'none'),
'server_to_client' => array(
'crypt' => 'aes256-cbc,aes192-cbc,aes128-cbc',
'comp' => 'none'));
$callbacks = array();
$this->con = ssh2_connect($host, $port, $methods, $callbacks);
if (!$this->con) die('Connection failed');
else {
if (!ssh2_auth_password($this->con, $user, trim($pass))) {
die("login failed.");
}
}
return true;
}
/* Befehle ausführen */
public function ssh_exec ($cmd, $stderr=true)
{
if ($stderr == true)
{
$stream = ssh2_exec($this->con, $cmd);
$err_stream = ssh2_fetch_stream($stream, SSH2_STREAM_STDERR);
stream_set_blocking($err_stream, true);
$result_err = stream_get_contents($err_stream);
if (empty($result_err))
{
stream_set_blocking($stream, true);
$out = stream_get_contents($stream);
return $out;
}
else {
return $result_err;
}
}
else {
$stream = ssh2_exec($this->con, $cmd);
stream_set_blocking($stream, true);
$out = stream_get_contents($stream);
return $out;
}
}
/* Verbindung beenden */
public function quit()
{
$stream = ssh2_exec($this->con, 'exit');
stream_set_blocking($stream, true);
$output = stream_get_contents($stream);
return true;
}
}
In my case I stored Serveraccounts in MySQL Table with encrypted password.
hope that little class helps
if you want to "write it yourself" you could mix bash,php and/or other scripting..