Adldap2 authentication always returns true - Yii2 - yii2

I'm working in Yii2 with the Adldap extension found here: https://github.com/Adldap2/Adldap2
I'm running into an issue when I try to authenticate users on my ldap server. I can successfully make a connection and and retrieve user data, but when trying to authenticate if a user's username and password are correct or not, it always returns true, even if the creds are wrong. Below is my code snippet (with the config array not showing of course):
$ad->addProvider($config);
try {
// If a successful connection is made to your server, the provider will be returned.
$provider = $ad->connect();
//User below does return the correct information from the ldap server
$user = $provider->search()->users()->find('quillin');
try{
$provider->auth()->attempt("wrongUsername","wrongPassword");
die("WIN");
}catch( Exception $e ){
die("Exception " . $e);
}
}catch (\Adldap\Auth\BindException $e) {
die( "There was an issue binding / connecting to the server. <br />" . $e);
}
No matter what I put in for the username and password fields, it always returns true and hits the die("WIN"); line. In my composer.json file, i'm using "adldap2/adldap2": "v7.0.*"
I have also tried to bind the user using the following:
try{
$provider->auth()->attempt("wrongUsername","wrongPassword", $bindAsUser = true);
die("WIN");
}catch( Exception $e ){
die("lose :(");
die("Exception " . $e);
}
And that also always returns true;

I figured this out and will explain here in anyone else has the same issue.
1) $provider->auth()->attempt() should be wrapped in an IF, and not a try/catch.
2) The first parameter, $username, is actually looking for the userprincipalname, the docs had made it sound like it was looking instead for a username.
After that, I was able to authenticate the user successfully.

Related

How to create user on hMailServer programatically?

We are writing a specialized PHP e-mail client and would like to give administrators of this client the ability to create user accounts on hMailServer.
I tried out imap_createmailbox(...) but it just creates a directory in the user's folder structure but does not "create a mailbox for a new user" as we want.
Is there some kind of interface that hMailServer has so that I can enable our PHP e-mail client to create hMailServer accounts via code?
Yes there two interfaces to create accounts in hmailserver.
One, via database, you can choose account and password hash type (0,1,2,3) and signature and other classic informations. I don't recommend this method for synchronisation reason, hmail-server take a caching time to consider the database update.
Two, which i recommend is to use API COM, its offers all possible methods in all cummon languages.
You have to enable D-COM in your windows server.
The API guide
hmailserver version: hMailServer 5.6.4 - Build 2283
complete solution of create new email account by hmailserver in c#
if you have configured hmailserver successfully, so then you can use the following steps to create new account by hmailserver in c#
hmailserver connection
private Domain HMailServerConnection() {
var objGlobal = new ApplicationClass();
objGlobal.Authenticate(ConfigurationManager.AppSettings["HMailUsername"], ConfigurationManager.AppSettings["HMailPassword"]);
return objGlobal.Domains.get_ItemByName(ConfigurationManager.AppSettings["hMailDomain"]);
}
function to create new email account
public string AddNewAccount(string email,string password)
{
try
{
Domain domain = HMailServerConnection();
Accounts accounts = domain.Accounts;
Account mailbox = accounts.Add();
mailbox.Address = email;
mailbox.Password = password;
mailbox.Save();
return "success";
}
catch(Exception ex)
{
return "error";
}
}
App settings in App.config or web.config
<appSettings>
<add key="hMailDomain" value="domainname"/>
<add key="HMailUsername" value="Username"/>
<add key="HMailPassword" value="password"/>
</appSettings>
see the link
its working i tested it.
<?php
header('Content-Type: text/html; charset=utf-8');
$obBaseApp = new COM("hMailServer.Application", NULL, CP_UTF8);
$obBaseApp->Connect();
$hmail_config['rooturl'] = "http://localhost/";
$obAccount = $obBaseApp->Authenticate("Administrator", "hMailserver Administrator
password");
if (!isset($obAccount)) {
echo "<b>Not authenticated or Administrator's password wrong</b>";
} else {
try {
echo "<b>Logon COM [OK], now we can add accounts</b>";
$obDomain = $obBaseApp->Domains->ItemByDBID(1);
$obAccount = $obDomain->Accounts->ItemByDBID(1); // account id
$domainname = $obDomain->Name;
$obAccounts = $obDomain->Accounts();
$obAccount = $obDomain->Accounts->Add();
$newalias = "powerranger";
$firstname = "Arnold";
$lastname = "Schwarzenegger";
$my_domainname ="#mydomain.com";
$obAccount->PersonFirstName = $firstname;
$obAccount->PersonLastName = $lastname;
$obAccount->MaxSize = 102; // 102 MB set inbox space
$obAccount->Address = $newalias .$my_domainname;
$obAccount->Password = "secret"; // provide this in Thunderbird/Outlook ect.
$obAccount->Active = true; // set account to active
$obAccount->Save(); // save, finish.
/* If we reaching this point, everything works as expected */
echo "<br/><h3> Account was successfully created, now you can login with".
"an POP3 or IMAP-Client </h3>";
}
/* OK, if something went wrong, give us the exact error details */
catch(Exception $e) {
echo "<h4>COM-ERROR: <br />".$e->getMessage()."</h4><br />";
}
}

Can't catch my mysql errors

I am using codeigniter for my server side in php.
I set my email field UNIQUE on my Users table.
The problem is that whatever I tried I can't catch the error mysql generated when trying to insert a duplicate email.
What i tried inside my model:
function insert($arr) {
$query= $this->CI->db->insert('user', $arr);
if($query){
return $this->CI->db->insert_id();
} else {
$msg = $this->CI-db->_error_message();
return $msg;
}
}
The issues goes that everything is fine until I get a duplicate and I actually get NOTHING inside the $msg. I know debug is on from the database config file.
If your database config 'db_debug' => TRUE, your code will exit with showing the error message and you will not able to reach this line $msg = $this->CI-db->_error_message();.
So to catch the error message you need to set the.
db_debug' => FALSE
At CI-2 your above code will work.See more at this question
But At CI-3 those function is not available and it will produce php undefined method error. CI-3 has a method display_error. You can check it.
My solution: If you want the errors you can get it using this line
$msg = $this->db->conn_id->error_list;
This will give you the error lists as array.But remember you need to set db_debug' => FALSE

Codeigniter remote connection does not return queries

I have a local and a remote connection with my mysql database. The local connection works just fine. But the remote connection, while it makes a connection, it does not return anything. I usually get the following:
Fatal error: Call to a member function result() on a non-object
I use for the remote connection the following configuration:
$db['mydb']['hostname'] = "ip_address_of_database";
$db['mydb']['username'] = "username";
$db['mydb']['password'] = "password";
$db['mydb']['database'] = "database";
$db['mydb']['dbdriver'] = "mysql";
$db['mydb']['dbprefix'] = "";
$db['mydb']['pconnect'] = FALSE;
$db['mydb']['db_debug'] = FALSE;
$db['mydb']['cache_on'] = FALSE;
$db['mydb']['cachedir'] = "";
$db['mydb']['char_set'] = "utf8";
$db['mydb']['dbcollat'] = "utf8_general_ci";
In my function that accesses the database I check if there is a connection with the remote server and then I try to retrieve data.
$mydb = $this->load->database('mydb', TRUE);
if (!isset($mydb->conn_id) && !is_resource($mydb->conn_id)) {
$error = 'database is not connected';
return $error;
}else{
$query = $mydb->query("SELECT * FROM database LIMIT 1;");
return $query->result();
}
This works fine in the localhost database but not in the remote database. I allways get the error
Fatal error: Call to a member function result() on a non-object
Can you please help? What am I doing wrong? I stuck on this.
Finally, I found the solution after contacting my web hosting provider. The issue had to do with the Remote database access and their servers. The IP address exception and the domain name that I had added didn’t do the job. I had to add an internal domain name that my host was using in order the Remote database access to be allowed. I spent 2-3 hours chatting with them in order to find a solution.
Anyway now is solved. I am posting that FYI.

Solving "MySQL server has gone away" errors

I have written some code in PHP that returns the html content from .edu domains. A brief introduction is given here: Errors regarding Web Crawler in PHP
The crawler works fine when the number of links to crawl are small (something around 40 URLS) but I am getting "MySQL server has gone away" error after this number.
I am storing html content as longtext in MySQL tables and I am not getting why the error arrives after at least 40-50 insertions.
Any help in this regard is highly appreciated.
Please note that I have already altered the wait_timeout and max_allowed_packet to accomodate my queries and the php code and now I don't know what to do. Please help me in this regard.
You might be inclined to handle this problem by "pinging" the mysql server before a query. This is a bad idea. For more on why, check this SO post: Should I ping mysql server before each query?
The best way to handle the issue is by wrapping queries inside try/catch blocks and catching any database exceptions so that you can handle them appropriately. This is especially important in long running and/or daemon type scripts. So, here's a very basic example using a "connection manager" to control access to DB connections:
class DbPool {
private $connections = array();
function addConnection($id, $dsn) {
$this->connections[$id] = array(
'dsn' => $dsn,
'conn' => null
);
}
function getConnection($id) {
if (!isset($this->connections[$id])) {
throw new Exception('Invalid DB connection requested');
} elseif (isset($this->connections[$id]['conn'])) {
return $this->connections[$id]['conn'];
} else {
try {
// for mysql you need to supply user/pass as well
$conn = new PDO($dsn);
// Tell PDO to throw an exception on error
// (like "MySQL server has gone away")
$conn->setAttribute(
PDO::ATTR_ERRMODE,
PDO::ERRMODE_EXCEPTION
);
$this->connections[$id]['conn'] = $conn;
return $conn;
} catch (PDOException $e) {
return false;
}
}
}
function close($id) {
if (!isset($this->connections[$id])) {
throw new Exception('Invalid DB connection requested');
}
$this->connections[$id]['conn'] = null;
}
}
class Crawler {
private $dbPool;
function __construct(DbPool $dbPool) {
$this->dbPool = $dbPool;
}
function crawl() {
// craw and store data in $crawledData variable
$this->save($crawledData);
}
function saveData($crawledData) {
if (!$conn = $this->dbPool->getConnection('write_conn') {
// doh! couldn't retrieve DB connection ... handle it
} else {
try {
// perform query on the $conn database connection
} catch (Exception $e) {
$msg = $e->getMessage();
if (strstr($msg, 'MySQL server has gone away') {
$this->dbPool->close('write_conn');
$this->saveData($val);
} else {
// some other error occurred
}
}
}
}
}
I have another answer that deals with what I think is a similar problem, and it would require a similar answer. Basically, you can use the mysql_ping() function to test the connection before your insert. Before MySQL 5.0.14, mysql_ping() would automatically reconnect the server, but now you have to build your own reconnect logic. Something similar to this should work for you:
function check_dbconn($connection) {
if (!mysql_ping($connection)) {
mysql_close($connection);
$connection = mysql_connect('server', 'username', 'password');
mysql_select_db('db',$connection);
}
return $connection;
}
foreach($array as $value) {
$dbconn = check_dbconn($dbconn);
$sql="insert into collected values('".$value."')";
$res=mysql_query($sql, $dbconn);
//then some extra code.
}
I was facing "Mysql server has gone away" error while using Mysql connector 5.X, replacing dll to the last version solved the problem.
Are you opening a single DB connection and reusing it? Is it possible that its a simple timeout? You might be better served by opening a new DB connection for each of your read/write operations (IE contact .edu, get text, open DB, write text, close db, repeat).
Also how are you using the handle? Is it possible that it has hit an error and has 'gone away' for that reason?
Well This is what I am doing now based on rdlowrey's suggestion and I guess this is also right.
public function url_db_html($sourceLink = NULL, $source) {
$source = mysql_real_escape_string($source);
$query = "INSERT INTO html (id, sourceLink, sourceCode)
VALUES (NULL,('$sourceLink') , ('$source'))";
try {
if(mysql_query($query, $this->connection)==FALSE) {
$msg = mysql_errno($this->connection) . ": " . mysql_error($this->connection);
throw new DbException($msg);
}
} catch (DbException $e) {
echo "<br><br>Catched!!!<br><br>";
if(strstr($e->getMessage(), 'MySQL server has gone away')) {
$this->connection = mysql_connect("localhost", "root", "");
mysql_select_db("crawler1", $this->connection);
}
}
}
So once the query has failed to execute, the script will skip it but will make sure the connection is re-established.
However, my web crawler is crashing when files such as .jpg, .bmp, .pdf, etc are encountered. Is there a way to skip those urls containing these extensions. I am using preg_match and has given pdf and doc to match. Yet I want the function to skip all links containing extensions such as mp3, pdf, etc. Is this possible??

MySQL, Asterisk Dialplans and call forwarding

How do I get Asterisk to forward incoming calls based on matching the incoming call number with a number to forward to? Both numbers are stored in a MySQL database.
Sorry for the long code sample, but more than half of it is debugging code to help you get it set up.
I'm assuming your server already has a modern version of PHP (at /usr/bin/php) with the PDO library, and that you have a database table named fwd_table with columns caller_id and destination.
In /var/lib/asterisk/agi-bin get a copy of the PHP AGI library. Then create a file named something like forward_by_callerid.agi that contains:
#!/usr/bin/php
<?php
ini_set('display_errors','false'); //Supress errors getting sent to the Asterisk process
require('phpagi.php');
$agi = new AGI();
try {
$pdo = new PDO('mysql:host='.$db_hostname.';dbname='.$db_database.';charset=UTF-8', $db_user, $db_pass);
} catch (PDOException $e) {
$agi->conlog("FAIL: Error connecting to the database! " . $e->getMessage());
die();
}
$find_fwd_by_callerid = $pdo->prepare('SELECT destination FROM fwd_table WHERE caller_id=? ');
$caller_id = $agi->request['agi_callerid'];
if($callerid=="unknown" or $callerid=="private" or $callerid==""){
$agi->conlog("Call came in without caller id, I give up");
exit;
}else{
$agi->conlog("Call came in with caller id number $caller_id.");
}
if($find_fwd_by_callerid->execute(array($caller_id)) === false){
$agi->conlog("Database problem searching for forward destination (find_fwd_by_callerid), croaking");
exit;
}
$found_fwds = $find_fwd_by_callerid->fetchAll();
if(count($found_fwds) > 0){
$destination = $found_contacts[0]['destination'];
$agi->set_variable('FWD_TO', $destination);
$agi->conlog("Caller ID matched, setting FWD_TO variable to ''");
}
?>
Then from the dial plan you can call it like this:
AGI(forward_by_callerid.agi)
And if your database has a match, it will set the variable FWD_TO with goodness. Please edit your question if you need more help getting this integrated into your dial plan.
This article should do the trick. It's about 3 lines of code and some simple queries to add and remove forwarding rules.
The solution I was looking for ended up looking like this:
[default]
exten => _X.,1,Set(ARRAY(${EXTEN}_phone)=${DTC_ICF(phone_number,${EXTEN})})
exten => _X.,n(callphone),Dial(SIP/metaswitch/${${EXTEN}_phone},26)
exten => _X.,n(end),Hangup()