FrontPage様が紹介されていたソースが一部崩れていたので分かる範囲で修正してメモしておきます。
注)うちのレンタルサーバでの使用は厳禁です。発覚しだい即アカウント停止します。
#!/usr/bin/suidperl -T #################################################################### ### ### newpasswd --- Webインタフェースからのパスワード変更CGI ### ### Authen::PAMモジュールが必要 ### chown root:root newpasswd ### chmod 4555 newpasswd ### #################################################################### ### /etc/pam.d/newpasswd の内容 #################################################################### ### #%PAM-1.0 ### auth required pam_stack.so service=system-auth ### account required pam_stack.so service=system-auth ### password required pam_stack.so service=system-auth #################################################################### use CGI qw(:standard); # CGIモジュールの宣言 use Authen::PAM; # Authen::PAMモジュールの宣言 $q = CGI->new(); # CGIモジュールの初期化 $q->import_names('P'); # 「$P::変数」でアクセスできるようにする $homepage = "./"; # ホームページ $myself = "./newpasswd.cgi"; # このCGIのURL $pam_service="newpasswd"; # PAMサービス名 $cmsg = ""; # エラー・メッセージの初期化 sub conv { # PAMとの情報交換のための関数 my @res; # 戻値を保存する変数の初期化 while ( @_ ) { # 与えられたパラメータの処理 my $mtype = shift; # メッセージの種類 my $msg = shift; # メッセージ my $ans = ""; # 入力する反応 if ($mtype == PAM_ERROR_MSG()) { # エラーメッセージの処理 $cmsg .= "$msg<BR>n"; # エラーを記録 } elsif ($mtype == PAM_TEXT_INFO()) { # なんらかのテキスト $cmsg .= "$msg<BR>n"; # そのまま記録 } elsif ($mtype == PAM_PROMPT_ECHO_OFF()) { # プロンプト if ($pam_state eq "AUTHENTICATE") { # ユーザー認証を要求 $ans = $P::old; # 現在のパスワードを入力 $pam_state = "CHAUTH-AUTHEN"; # ステータスにパスワード変更認証をセット } elsif ($pam_state eq "CHAUTH-AUTHEN") { # パスワード変更のための認証が要求されている場合の処理 $ans = $P::old; # 現在のパスワードを入力 $pam_state = "CHAUTHTOK"; # ステータスにパスワード変更をセット } else { # 新パスワードの処理 $ans = $P::new; # 新しいパスワードをセット } $cmsg .= "$msg<BR>n"; # メッセージがあれば記録 } else { # プロンプトが表示されない場合 $cmsg .= "Error. $msg<BR>n"; # エラーメッセージを記録 }; push @res, (0, $ans); # 戻値をセット } push @res, PAM_SUCCESS(); # 成功のステータスをセット return @res; # 関数の終了 } sub stringcheck { # 不適当な文字列をチェック my $str = shift; # チェックする文字列を$strにセット return 1 if ($str =~ /[\000-\037177-377]/); # パスワード用文字列のチェック return 2 if ($str !~ /^(w[w-"]+)$/); # ユーザー名文字列のチェック return 0; # エラーなし } ## ## HTMLの用意 ## print header(-charset=>'EUC-JP'); # へッダの出力。文字コードにEUC-JPを指定する print start_html(-title=>'パスワード変更',-lang=>"ja",-encoding=>"EUC-JP"); # Webページの<HEAD>タグの内容をセット。ここでは言語(lang)と文字コード(EUC-JP)を指定する # print header(-charset=>'Shift_JIS'); # シフトJISでスクリプトを作成する場合は、charsetにShift_JISを指定する # print start_html(-title=>'パスワード変更',-lang=>"ja",-encoding=>"Shift_JIS"); # シフトJISでスクリプトを作成する場合は、encodingにShift_JISを指定する print h1('パスワード変更'); # タイトルの表示 if (! $P::flag) { # $flagが設定されていなければ、入力フォームを表示 ## ## このブロックでは最初の入力画面を表示させる。 ## print p("パスワードを変更します。"); print start_form(-method=>post,-action=>$myself); # フォームの開始。ここでは安全のためにPOSTメソッドを使う。 print hidden(-name=>"flag", -value=>"x"), # $flagにダミーの値をセット p("ユーザーID: ", textfield(-name=>"username")), # ユーザーIDの入力欄 p("現在のパスワード: ", password_field(-name=>"old")), # 古い(現在の)パスワードの入力欄 p("新しいパスワード: ", password_field(-name=>"new")), # 新しいパスワードの入力欄 p("新しいパスワード(再入力): ", password_field(-name=>"new2")), # 確認のための新しいパスワードの再入力欄 p(submit("変更")); # 変更ボタンの表示 print end_form; # フォームの終了 } else { # $flagがセットされている場合は、入力データが存在するものとみなしてパスワードの変更を行う ## ## ユーザー名、パスワードのチェック ## if ($P::new ne $P::new2) { # 新パスワードの誤入力チェック print p("新パスワードと確認用に入力したパスワードが違っています。"), p("パスワードを入力し直してください。"); } elsif (length($P::new) < 8 || length($P::new) > 255) { # 新パスワードの長さのチェック print p("8文字以上255文字以下のパスワードを入力してください。"); } elsif (length($P::username) < 2 || length($P::username) > 10) { # ユーザー名の入力チェック print p("ユーザー名を入力してください。"); } elsif (stringcheck($P::username)) { # ユーザー名として不適当な文字があればエラー print p("ユーザー名が不適切です。"); } elsif (stringcheck($P::new) == 1) { # パスワードにコントロールコードが含まれている場合はエラー print p("新しいパスワードに不適切な文字が含まれています。"); } else { # 問題がなければパスワード変更処理を行う ## ## PAMによる認証とパスワードの変更 ## $prv = pam_start($pam_service, $P::username, &conv, $pamh); # PAMの初期化 $pam_state = "AUTHENTICATE"; # 最初は認証を行う $prv = pam_authenticate($pamh, 0); # 認証を実行 if ($prv != PAM_SUCCESS) { # 認証に失敗した場合はエラー print p("認証エラー:", pam_strerror($pamh, $prv)); } else { # 認証が通ればパスワードの変更 $prv = pam_chauthtok($pamh); # パスワード変更処理 if ($prv != PAM_SUCCESS) { # パスワード変更に失敗した場合はエラー print p("トークン変更失敗:", pam_strerror($pamh, $prv)); } }; ## ## 結果の表示 ## if ($prv == PAM_SUCCESS ) { # PAMからの戻値が成功であれば無事終了 print p("パスワードを変更しました。"); } else { # PAMからの戻値がエラーなら、メッセージを表示して終了 print p("パスワードの変更に失敗しました。"); print p($cmsg); }; $prv = pam_end($pamh, 0); # PAMの終了処理 }; }; print hr, "<A HREF="$myself">元に戻る</A> | <A HREF="$homepage">ホームページ</A>"; # フッタのリンクを表示 print end_html; # HTMLの終了 ##
0 Comments.