Linuxパスワード変更CGI

[2002-09-11 補記] 改訂する暇がないが,パスワード認証 の仕組みを説明するページを作っておいた。 以前に書いたCのサンプルソースの改訂版も付けた。


Linuxでパスワード変更を行うCGIを作ってみました。

CGIを呼び出すページは次のように作っておきます。

<html>
<head>
<meta name="robots" content="noindex,nofollow">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Content-Type" content="text/html; charset=EUC-JP">
<title>パスワード変更</title>
</head>
<body>
<h1>パスワード変更</h1>
<p>
<form action="usermod.cgi" method="post">
<p>ユーザ名: <input type="text" name="user" size=10>
<p>旧パスワード: <input type="password" name="oldpass" size=10>
<p>新パスワード: <input type="password" name="newpass1" size=10>
<p>新パスワード: <input type="password" name="newpass2" size=10>
<p>
<input type="submit" value="送る">
<input type="reset" value="やりなおし">
</form>
</body>
</html>

C++のプログラム usermod.cc をスーパユーザ権限で

# g++ usermod.cc -o usermod.cgi -lcrypt
# chmod 4755 usermod.cgi
のようにしてコンパイルし suid root しておきます。

[2003-04-30] 小山さん [linux-users:98966] のパッチを取り入れさせていただきました。

PAM対応版その1

上の usermod.cc は従来のパスワード形式でしか使えません。 最近のシステムでは,パスワードの頭8文字までが有効な従来の形式と,長いパスワードが使える md5 形式とが選べるようになっているものが多いようです。 md5 形式も含めてパスワードを書き換えるには Linux PAM に対応した usermod2.cc のほうをお使いください。 コンパイルは

# g++ usermod2.cc -o usermod.cgi -lpam
# chmod 4511 usermod.cgi
のようにします。

poppassd (ftp://ftp.qualcomm.com/eudora/servers/unix/password/linux-poppassd-1.tar.gz) のソースコードを参考にさせていただきました。

PAM対応版その2

学生のパスワードはスーパーユーザ以外の教職員にも変更できたほうがいいので, usermod3.cc のようにしてみました。

これは,

を入れて呼ぶと,たとえば wde73359 のようなランダムなパスワードを設定します。 ランダムにしたのは,教職員が勝手に学生のパスワードを変更してメールを読み, また元に戻してわからなくするといった疑いを持たれるのを防ぐためです。

さらに,誰がいつパスワード変更の保証人になったかも syslog に残すようにしました。

このコードでは pam_strerror() という関数が使われています。 ところがこれは現 glibc のヘッダファイルがおかしいので C++ ではエラーになります。 対策として,pam_strerror() のある行を消すか, あるいは /usr/include/security/_pam_types.h の関数プロトタイプ宣言部分を extern "C" { } で囲みます:

#ifdef __cplusplus
extern "C" {
#endif

extern int pam_set_item(pam_handle_t *pamh, int item_type, const void *item);
extern int pam_get_item(const pam_handle_t *pamh, int item_type,
			const void **item);
extern const char *pam_strerror(pam_handle_t *pamh, int errnum);

extern int pam_putenv(pam_handle_t *pamh, const char *name_value);
extern const char *pam_getenv(pam_handle_t *pamh, const char *name);
extern char **pam_getenvlist(pam_handle_t *pamh);

#ifdef __cplusplus
}
#endif

[2003-06-13] popauth で APOP パスワードも同時に変えるように急場ごしらえの変更をしました。

PAM対応版その2――Solaris対応

Solaris 2.7 ではそのままではうまくいかず,試行錯誤の末 usermod3-solaris.cc を作りました。 十分テストしていませんのでおかしいかもしれません。


奥村晴彦

Last modified: 2004-05-27 21:06:23