<?php
 
/**
 *
 *
 *   LDAP PHP Change Password Webpage
 *
 *   Adapted for FUSS by: Christopher R. Gabriel <cgabriel@truelite.it>
 *   	     	      	  Simone Piccardi <piccardi@truelite.it>
 *
 *   Based on work by:
 *
 *   @author:   Matt Rude <http://mattrude.com>
 *   @website:  http://technology.mattrude.com/2010/11/ldap-php-change-password-webpage/
 *
 *
 *              GNU GENERAL PUBLIC LICENSE
 *                 Version 2, June 1991
 *
 * Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 * Everyone is permitted to copy and distribute verbatim copies
 * of this license document, but changing it is not allowed.
 */
 
$message = array();
$message_css = "";
 
function changePassword($user,$oldPassword,$newPassword,$newPasswordCnf){
  global $message;
  global $message_css;
 
  $server = "localhost";
  $dn = "ou=Users,{{ basedn }}";
    
  error_reporting(0);
  ldap_connect($server);
  $con = ldap_connect($server);
  ldap_set_option($con, LDAP_OPT_PROTOCOL_VERSION, 3);
   
  // bind anon and find user by uid
  $user_search = ldap_search($con,$dn,"(&(uid=$user)(ou=studenti))");
  $user_get = ldap_get_entries($con, $user_search);
  if ( $user_get["count"] == 0 ) {
      $user_research = ldap_search($con,$dn,"(uid=$user)");
      $user_reget = ldap_get_entries($con, $user_research);
      if ( $user_reget["count"] != 0 ) {
      	  // we got a non student here
	  $user_search = $user_research;
	  $user_get = $user_reget;
      } else {
          $message[] = "Errore E101 - Utente e/o password attuali non corretti.";
          return false;
      }
  }
  $user_entry = ldap_first_entry($con, $user_search);
  $user_dn = ldap_get_dn($con, $user_entry);
  $user_id = $user_get[0]["uid"][0];
   
  if (ldap_bind($con, $user_dn, $oldPassword) === false) {
    $message[] = "Errore E101 - Utente e/o password attuali non corretti.";
    return false;
  }
  if ($newPassword != $newPasswordCnf ) {
    $message[] = "Errore E102 - Le tue nuove password non sono uguali!";
    return false;
  }
  if (preg_match('/[^A-Za-z0-9]/', $newPassword)) {
    $message[] = "Errore E103 - La nuova password contiene caratteri non permessi da questa interfaccia";
    return false;
  }

  // added check for non student users
  if ( $user_reget["count"] != 0 ) {
    if (strlen($newPassword) < 8 ) {
      $message[] = "Errore E104 - La nuova password deve contenere almeno 8 caratteri!";
      return false;
    }    
    if (!preg_match("#[0-9]+#", $newPassword)) {
      $message[] = "Errore E104 - La nuova password deve contenere almeno un numero!";
      return false;
    }
    if (!preg_match("#[a-z]+#", $newPassword)) {
      $message[] = "Errore E104 - La nuova password deve contenere almeno una minuscola!";
      return false;
    }     
    if (!preg_match("#[A-Z]+#", $newPassword)) {
      $message[] = "Errore E104 - La nuova password deve contenere almeno una maiuscola!";
      return false;
    }     
  }

  if (!$user_get) {
    $message[] = "Errore E200 - Impossibile collegarsi al server, nessuna modifica effettuata. Contatta il tuo amministratore di sistema.";
    return false;
  }
  
  // TODO: this should be changed to use exop and ldap_exop_passwd
  $encoded_newPassword = "{SHA}" . base64_encode( pack( "H*", sha1( $newPassword ) ) );

  $auth_entry = ldap_first_entry($con, $user_search);

  $entry = array();
  $entry["userPassword"] = "$encoded_newPassword";
  $NTpass=iconv('UTF-8','UTF-16LE',$newPassword);
  $NTLMHash = hash('md4',$NTpass);
  $entry["sambaNTPassword"] = "$NTLMHash";

   
  if (ldap_modify($con,$user_dn,$entry) === false){
    $error = ldap_error($con);
    $errno = ldap_errno($con);
    $message[] = "Errore E201 - La tua password non può essere modificata, contatta il tuo amministratore di sistema.";
    $message[] = "$errno - $error";
  } else {
    // Change kerberos password
    $e_user = escapeshellarg($user);
    $e_old_pwd = escapeshellarg($oldPassword);
    // newPassword has been checked to contain just alnum characters and user_id
    // comes from ldap, so they should be safe unescaped
    $e_command = "'cpw -pw $newPassword $user_id@{{ domain | upper }}'";

    $kadmin_command = "kadmin -p $e_user@{{ domain | upper }} -w $e_old_pwd -q $e_command ";
    $res = exec($kadmin_command, $output, $retval);
    if ($retval != 0) {
      $message[] = "Errore E300 - Il cambiamento di password non è stato completato, contatta il tuo amministratore di sistema.";
    } else {
    // and then tell the user that the change was successful
      $message_css = "yes";
      $message[] = "La password per l'utente $user_id è stata cambiata.<br/>La tua nuova password è già attiva.";
    }
  }

}
 
?>
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">
    <title>FUSS Server Password Changer</title>

    <link href="css/bootstrap.min.css" rel="stylesheet">
    <script type="text/javascript" src="js/bootstrap.min.js"></script>
    <!-- Custom styles for this template -->
  </head>

  <body>

   <div class="container-fluid">
     <div class="col-md-4">
        <img class="center-block" src="logo.png">			
        <h2 class="form-signin-heading">Cambia password</h2>
	<p>Inserisci il tuo nome utente, la tua password attuale, e ripeti due volte la nuova password che vuoi adottare.</p>

       </div>
     <div class="col-md-8">
      <form class="form-signin" role="form" method="post" name="passwordChange" action="<?php print $_SERVER['PHP_SELF']; ?>">
	<?php
	   if (isset($_POST["submitted"])) {
           changePassword($_POST['username'],$_POST['oldPassword'],$_POST['newPassword1'],$_POST['newPassword2']);
           global $message_css;
           if ($message_css == "yes") {
           ?><div class="alert alert-success"><?php
				     } else {
						 ?><div class="alert alert-danger"><?php
										      $message[] = "Your password was not changed.";
							      }
							      foreach ( $message as $one ) { echo "<p>$one</p>"; }
							      ?></div><?php
      } ?>

	  <input name="username" class="form-control" placeholder="Nome utente" required autofocus type="text" size="20px" autocomplete="off" />

	  <input name="oldPassword" size="20px" type="password" placeholder="Password attuale" class="form-control" required/>

	  <input name="newPassword1" size="20px" type="password" placeholder="Nuova password" class="form-control" required/>

	  <input name="newPassword2" size="20px" type="password" placeholder="Ripeti nuova password" class="form-control" required/>

	  <input class="btn btn-success btn-lg btn-block" name="submitted" type="submit" value="Cambia password"/>
	  <button class="btn btn-danger btn-lg btn-block" onclick="$('frm').action='changepassword.php';$('frm').submit();">Annulla</button>

      </form>
</div>
    </div> <!-- /container -->

  </body>
</html>







