Как позволить пользователям изменять пароль linux через веб-браузер? [закрыто]

Я не уверен, что это вопрос stackoverflow или serverfault, но вот:

У меня файловый сервер Ubuntu 10.04 (Samba/FTP/HTTP), и я хотел бы иметь возможность дать пользователям возможность изменить свой пароль к серверу через веб-браузер.

Я уже писал подобный скрипт, используя PHP и набор exec, но я считаю, что это небезопасно, потому что его может прослушать кто-то, просматривая список процессов на сервере.

Есть ли какой-нибудь плагин (PHP или Python или другой), который может сделать это легко?

Я предпочитаю не использовать что-то вроде webmin/usermin, так как это слишком сложно для этого.

7
задан 11 June 2010 в 05:23
5 ответов

После часов исследования онлайн, я не смог найти супер хороший вариант, таким образом, я реализован этот взлом. Это использует эту статью для изменения паролей с помощью PHP.

Я также использую пакет PECL:PAM для добавления небольшой проверки.

Эта страница находится на безопасной папке HTTPS (автоматическое перенаправление через .htaccess)

<?php

$messages = array();

function change_password ($user, $currpwd, $newpwd) {

    // Open a handle to expect in write mode
    $p = popen('/usr/bin/expect','w');

    // Log conversation for verification
    $log = '/tmp/passwd_' . md5($user . time());
    $cmd .= "log_file -a \"$log\"; ";

    // Spawn a shell as $user
    $cmd .= "spawn /bin/su $user; ";
    $cmd .= "expect \"Password:\"; ";
    $cmd .= "send \"$currpwd\\r\"; ";
    $cmd .= "expect \"$user@\"; ";

    // Change the unix password
    $cmd .= "send \"/usr/bin/passwd\\r\"; ";
    $cmd .= "expect \"(current) UNIX password:\"; ";
    $cmd .= "send \"$currpwd\\r\"; ";
    $cmd .= "expect \"Enter new UNIX password:\"; ";
    $cmd .= "send \"$newpwd\\r\"; ";
    $cmd .= "expect \"Retype new UNIX password:\"; ";
    $cmd .= "send \"$newpwd\\r\"; ";
    $cmd .= "expect \"passwd: password updated successfully\"; ";

    // Commit the command to expect & close
    fwrite($p, $cmd); pclose ($p);

    // Read & delete the log
    $fp = fopen($log,r);
    $output = fread($fp, 2048);
    fclose($fp); unlink($log);
    $output = explode("\n",$output);

    return (trim($output[count($output)-2]) == 'passwd: password updated successfully') ? true : false;
}

function process_post() {

    if ((!isset($_SERVER['HTTP_REFERER'])) 
        || (strpos($_SERVER['HTTP_REFERER'], $_SERVER['SCRIPT_NAME']) === FALSE)) {

        echo "GO AWAY!";
        exit();
        return FALSE;

    }

    global $messages;

    $username           = trim($_POST['username']);
    $password_current   = trim($_POST['password_current']);
    $password_new       = trim($_POST['password_new']);
    $password_confirm   = trim($_POST['password_confirm']);

    // Check for blanks
    if ($username == '' || $password_current == '' || $password_new == '' || $password_confirm == '') {
        array_push(&$messages, "ERROR: You cannot leave any field empty.");
        return FALSE;
    }

    // Check username
    if (!ctype_alnum($username)) {
        array_push(&$messages, "ERROR: You've entered an invalid username.");
        return FALSE;
    }

    // Check to see if new password is correctly typed
    if ($password_new != $password_confirm) {       
        array_push(&$messages, "ERROR: New Password and Confirmation do not match.");
        return FALSE;
    }

    // Check if current password is valid (not really neccessary)
    if (!pam_auth($username, $password_current, &$error, FALSE)) {
        if (trim($error) == "Permission denied (in pam_authenticate)")
            array_push(&$messages, "ERROR: You've username/password was not accepted.");    
        else
            array_push(&$messages, "ERROR: " . $error);
        return FALSE;
    }

    if (change_password ($username, $password_current, $password_new))
        array_push(&$messages, "Password Successfully Changed");
    else 
        array_push(&$messages, "ERROR: Password change failed.");

}

if ($_SERVER['REQUEST_METHOD'] == 'POST') process_post();


?><html>
<head>


<title>Passwords</title>

<style type="text/css">

body {
    font-family: Verdana, Arial, sans-serif;
    font-size: 12px;
}

label {
    width: 150px;
    display: block;
    float: left;
}

input {
    float: left;
}

br {
    clear: both;
}

.message {
    font-size: 11px;
    font-weight: bold;
}

.error {
    color:#C00;
}


</style>

</head>


<body>

<h2>Change Passwords</h2>

<form action="<?= $_SERVER['SCRIPT_NAME'] ?>" method="post">

<fieldset>

<? if (count($messages) != 0) { 

    foreach ($messages as $message) { ?>

<p class="message<?= ((strpos($message, 'ERROR:') === FALSE) ? '' : ' error') ?>"><?= $message ?></p>

<? } } ?>

<label>Username: </label>
<input type="text" name="username" /><br />

<label>Current Password:</label>
<input type="password" name="password_current" /><br />

<label>New Password:</label>
<input type="password" name="password_new" /><br />

<label>Confirm Password:</label>
<input type="password" name="password_confirm" /><br />

<input type="reset" value="Reset" /> <input type="submit" value="Submit" />

</fieldset>


</form>


</body>
</html>

Мне также отправили этот вопрос/ответ в https://stackoverflow.com/questions/3032785/php-pam-to-change-user-password/3067974#3067974

0
ответ дан 2 December 2019 в 23:36

сеть-chpass может изменить пароли через PAM.

4
ответ дан 2 December 2019 в 23:36
  • 1
    Это выглядело очень перспективным, но я действительно не знаю, как использовать CGI Perl, и это выглядит немного датированным. –  wag2639 18 June 2010 в 10:54
  • 2
    @wag2639: Я не думаю "датированный", проблема; интерфейс PAM является все еще тем же. –  grawity 18 June 2010 в 14:10

При выполнении Samba как PDC, Вы могли бы использовать его, чтобы позволить пользователям изменять свой пароль с помощью ctrl+alt+delete. Я сожалею, если этот anwser не подходит Вам, но я не могу добавить комментарии или так еще...

    unix password sync = Yes

    passwd program = /usr/bin/php -f /my_folder/my_own_script.php %u
    passwd chat = "password:" %n\n "changed"
    passwd chat debug = yes

или системная программа:

passwd program = /usr/bin/passwd %u
passwd chat = *New*UNIX*password* %n\n *ReType*new*UNIX*password* %n\n  *passwd:*all*authentication*tokens*updated*successfully*

поиск "Синхронизации Пароля" это к середине документа и объясняет лучше, как это работает: http://www.samba.org/samba/docs/using_samba/ch09.html#samba2-CHP-9-SECT-4.3

1
ответ дан 2 December 2019 в 23:36

Вероятно, лучшее решение состояло бы в том, чтобы использовать некоторый интерфейс LDAP (например, от платформы программирования), или из поля frontend, как Webmin.

1
ответ дан 2 December 2019 в 23:36
  • 1
    я хотел использовать usermin, но он не будет работать и я не знаю, как диагностировать. Есть ли какие-либо альтернативы? –  wag2639 18 June 2010 в 06:23

I prefer to use 2 separate processes. One process makes a request by dropping a special file into a special folder. Second, a cron job loops through the folder and fulfills the password change requests.

All the calling script needs to do is drop the file into the folder (provided it has permissions to do so.

Please see this link for more details and to get the scripts: http://sylnsr.blogspot.com/2012/09/keep-unix-password-in-sync-with.html

2
ответ дан 2 December 2019 в 23:36

Теги

Похожие вопросы