From 400fa1787d5c2397468fe8274dfdfc9f75c461a7 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Tue, 30 May 2017 15:27:49 +0200 Subject: [PATCH] =?UTF-8?q?Sincronizaci=C3=B3n=20con=20LDAP?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- debian/changelog | 2 +- debian/control | 2 +- rest/core/account.php | 170 +++++++++++++++++++++++++++++++++--------- rest/core/login.php | 10 +++ 4 files changed, 148 insertions(+), 36 deletions(-) diff --git a/debian/changelog b/debian/changelog index afbb328e..6182d01a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -hedera-web (1.405.2) stable; urgency=low +hedera-web (1.405.3) stable; urgency=low * Initial Release. diff --git a/debian/control b/debian/control index 87ac690d..a3a71323 100644 --- a/debian/control +++ b/debian/control @@ -9,7 +9,7 @@ Vcs-Git: git://www.verdnatura.es/var/git/hedera-web Package: hedera-web 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 Section: misc Priority: optional diff --git a/rest/core/account.php b/rest/core/account.php index 1984e7ba..68188ef5 100755 --- a/rest/core/account.php +++ b/rest/core/account.php @@ -2,7 +2,20 @@ 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 ( 'SELECT COUNT(*) > 0 @@ -12,61 +25,142 @@ class Account [$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; - $conf = $db->getRow ( - 'SELECT sambaHost, homesHost, sshUser, sshPass - FROM account.accountConfig' - ); - $sshPass = base64_decode ($conf['sshPass']); - - $samba = new SshConnection ($conf['sambaHost'] - ,$conf['sshUser'] - ,$sshPass - ); - $homes = new SshConnection ($conf['homesHost'] - ,$conf['sshUser'] - ,$sshPass + // Gets LDAP configuration parameters + + $conf = $db->getObject ( + 'SELECT host, rdn, password, baseDn, filter + FROM account.ldapConfig'); + + // Connects an authenticates against server + + $ds = ldap_connect ($conf->host); + + if (!$ds) + throw new Exception ("Can't connect to LDAP server: ". ldapError ($ds)); + + 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 $userId = $db->getValue ( 'SELECT id FROM account.user WHERE name = #', [$user]); - $accConf = $db->getRow ( - 'SELECT uidBase, domain FROM account.accountConfig'); - $escUid = SshConnection::escape ($accConf['uidBase'] + $userId); - $escMail = SshConnection::escape ("$user@{$accConf['domain']}"); - - $samba->exec ( - "/mnt/cluster/scripts/create-user.sh $escUser $escUid $escMail"); - $homes->exec ( - "/mnt/storage/scripts/create-user.sh $escUser"); + $samba->exec ("$scriptDir/create-user.sh %s %s %s" + ,$user + ,$conf->uidBase + $userId + ,"$user@{$conf->domain}" + ); // Syncronizes the Samba password if (empty ($password)) return; - $escPassword = SshConnection::escape ($password); - $samba->exec ( - "/mnt/cluster/scripts/set-password.sh $escUser $escPassword"); - - new SshConnection ($conf['homesHost'], $user, $password); + $samba->exec ("$scriptDir/set-password.sh %s %s" + ,$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 { var $connection; /** * Abrebiated method to make SSH connections. - **/ + */ function __construct ($host, $user, $password) { $this->connection = $connection = ssh2_connect ($host); @@ -84,15 +178,23 @@ class SshConnection /** * 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); } /** * Escapes the double quotes from an string. - **/ + */ static function escape ($str) { return '"'. str_replace ('"', '\\"', $str) .'"'; diff --git a/rest/core/login.php b/rest/core/login.php index c1c02bb0..c0b58b31 100755 --- a/rest/core/login.php +++ b/rest/core/login.php @@ -1,9 +1,19 @@ service->createToken ( $_SESSION['user'], !empty ($_POST['remember'])