0
1
Fork 0

Sincronización con LDAP

This commit is contained in:
Juan Ferrer Toribio 2017-05-30 15:27:49 +02:00
parent 5b50b3cc64
commit 400fa1787d
4 changed files with 148 additions and 36 deletions

2
debian/changelog vendored
View File

@ -1,4 +1,4 @@
hedera-web (1.405.2) stable; urgency=low hedera-web (1.405.3) stable; urgency=low
* Initial Release. * Initial Release.

2
debian/control vendored
View File

@ -9,7 +9,7 @@ Vcs-Git: git://www.verdnatura.es/var/git/hedera-web
Package: hedera-web Package: hedera-web
Architecture: all Architecture: all
Depends: apache2, php5-mysql, php5-mcrypt, php5-ssh2, php-vn-lib, nodejs Depends: apache2, php5-mysql, php5-mcrypt, php5-ldap, php5-ssh2, php-vn-lib, nodejs
Suggests: php-text-captcha, php5-imap, tinymce Suggests: php-text-captcha, php5-imap, tinymce
Section: misc Section: misc
Priority: optional Priority: optional

View File

@ -2,7 +2,20 @@
class Account class Account
{ {
static function sync ($db, $user, $password = NULL) static function trySync ($db, $user, $password = NULL)
{
$isSync = $db->getValue (
'SELECT sync FROM account.user WHERE name = #',
[$user]
);
if ($isSync)
return;
self::sync ($db, $user, $password);
}
static function sync ($db, $user, $password = NULL, $force = TRUE)
{ {
$hasAccount = $db->getValue ( $hasAccount = $db->getValue (
'SELECT COUNT(*) > 0 'SELECT COUNT(*) > 0
@ -12,61 +25,142 @@ class Account
[$user] [$user]
); );
if (!$hasAccount) if ($hasAccount)
{
self::ldapSync ($db, $user, $password);
self::sambaSync ($db, $user, $password);
}
$db->query (
'UPDATE account.user SET sync = TRUE WHERE name = #',
[$user]
);
}
/**
* Synchronizes the user credentials in the LDAP server.
*/
static function ldapSync ($db, $user, $password)
{
if (empty ($password))
return; return;
$conf = $db->getRow ( // Gets LDAP configuration parameters
'SELECT sambaHost, homesHost, sshUser, sshPass
FROM account.accountConfig' $conf = $db->getObject (
); 'SELECT host, rdn, password, baseDn, filter
$sshPass = base64_decode ($conf['sshPass']); FROM account.ldapConfig');
$samba = new SshConnection ($conf['sambaHost'] // Connects an authenticates against server
,$conf['sshUser']
,$sshPass $ds = ldap_connect ($conf->host);
);
$homes = new SshConnection ($conf['homesHost'] if (!$ds)
,$conf['sshUser'] throw new Exception ("Can't connect to LDAP server: ". ldapError ($ds));
,$sshPass
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
$bind = ldap_bind ($ds, $conf->rdn, base64_decode ($conf->password));
if (!$bind)
throw new Exception ("Authentication failed on LDAP server: ". ldapError ($ds));
// Search the user entry
$res = ldap_search ($ds, $conf->baseDn, "(&(uid=$user)($conf->filter))");
if (!$res)
throw new Exception ("Can't get the LDAP entry: ". ldapError ($ds));
$dn = "uid=$user,{$conf->baseDn}";
$entry = ldap_first_entry ($ds, $res);
if ($entry)
{
$info = ['userPassword' => sshaEncode ($password)];
ldap_modify ($ds, $dn, $info);
}
else
{
$info = [
'objectClass' => ['account', 'simpleSecurityObject', 'top'],
'uid' => $user,
'userPassword' => sshaEncode ($password)
];
ldap_add ($ds, $dn, $info);
}
ldap_unbind ($ds);
}
/**
* Synchronizes the user credentials in the Samba server.
*/
static function sambaSync ($db, $user, $password)
{
$conf = $db->getObject (
'SELECT host, sshUser, sshPass, domain, uidBase
FROM account.sambaConfig'
); );
$escUser = SshConnection::escape ($user); $samba = new SshConnection ($conf->host
,$conf->sshUser
,base64_decode ($conf->sshPass)
);
$scriptDir = '/mnt/cluster/scripts';
// Creates the Samba user and initializes it's home directory // Creates the Samba user and initializes it's home directory
$userId = $db->getValue ( $userId = $db->getValue (
'SELECT id FROM account.user WHERE name = #', [$user]); 'SELECT id FROM account.user WHERE name = #', [$user]);
$accConf = $db->getRow (
'SELECT uidBase, domain FROM account.accountConfig');
$escUid = SshConnection::escape ($accConf['uidBase'] + $userId); $samba->exec ("$scriptDir/create-user.sh %s %s %s"
$escMail = SshConnection::escape ("$user@{$accConf['domain']}"); ,$user
,$conf->uidBase + $userId
$samba->exec ( ,"$user@{$conf->domain}"
"/mnt/cluster/scripts/create-user.sh $escUser $escUid $escMail"); );
$homes->exec (
"/mnt/storage/scripts/create-user.sh $escUser");
// Syncronizes the Samba password // Syncronizes the Samba password
if (empty ($password)) if (empty ($password))
return; return;
$escPassword = SshConnection::escape ($password); $samba->exec ("$scriptDir/set-password.sh %s %s"
$samba->exec ( ,$user
"/mnt/cluster/scripts/set-password.sh $escUser $escPassword"); ,$password
);
new SshConnection ($conf['homesHost'], $user, $password);
} }
} }
function ldapError ($ds)
{
return ldap_errno ($ds) .': '. ldap_error ($ds);
}
function sshaEncode ($value)
{
mt_srand ((double) microtime () * 1000000);
$salt = pack ('CCCC', mt_rand (), mt_rand (), mt_rand (), mt_rand ());
$hash = '{SSHA}' . base64_encode (pack ('H*', sha1 ($value . $salt)) . $salt);
return $hash;
}
function sshaVerify ($hash, $value)
{
$ohash = base64_decode (substr ($hash, 6));
$osalt = substr ($ohash, 20);
$ohash = substr ($ohash, 0, 20);
$nhash = pack ('H*', sha1 ($value . $osalt));
return $ohash == $nhash;
}
class SshConnection class SshConnection
{ {
var $connection; var $connection;
/** /**
* Abrebiated method to make SSH connections. * Abrebiated method to make SSH connections.
**/ */
function __construct ($host, $user, $password) function __construct ($host, $user, $password)
{ {
$this->connection = $connection = ssh2_connect ($host); $this->connection = $connection = ssh2_connect ($host);
@ -84,15 +178,23 @@ class SshConnection
/** /**
* Executes a command on the host. * Executes a command on the host.
**/ */
function exec ($command) function exec ()
{ {
$nargs = func_num_args ();
$args = func_get_args ();
for ($i = 1; $i < $nargs; $i++)
$args[$i] = self::escape ($args[$i]);
$command = call_user_func_array ('sprintf', $args);
error_log ($command);
return ssh2_exec ($this->connection, $command); return ssh2_exec ($this->connection, $command);
} }
/** /**
* Escapes the double quotes from an string. * Escapes the double quotes from an string.
**/ */
static function escape ($str) static function escape ($str)
{ {
return '"'. str_replace ('"', '\\"', $str) .'"'; return '"'. str_replace ('"', '\\"', $str) .'"';

View File

@ -1,9 +1,19 @@
<?php <?php
include __DIR__.'/account.php';
class Login extends Vn\Web\JsonRequest class Login extends Vn\Web\JsonRequest
{ {
function run ($db) function run ($db)
{ {
try {
Account::trySync ($db
,$_POST['user']
,$_POST['password']
);
}
catch (Exception $e) {}
$token = $this->service->createToken ( $token = $this->service->createToken (
$_SESSION['user'], $_SESSION['user'],
!empty ($_POST['remember']) !empty ($_POST['remember'])