人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

Linux で $HOME/.forward ファイルを書き換えるCGIを作りたいです。
私にはその為の難題が 2つあります。

1) 認証の方法が分かりません
/etc/{passwd,shadow} を使う!?
web で perl の getpwent関数を使ってるのを探したが、使い物にならなかった。

2) ファイルの書き換え方法が分かりません
CGIプロセスオーナーとファイル所有者の権限問題

言語は perl/ruby のいづれかで、具体的な回答が欲しいです。

●質問者: naopontan
●カテゴリ:コンピュータ インターネット
✍キーワード:CGI ETC HOME Linux Perl
○ 状態 :終了
└ 回答数 : 2/2件

▽最新の回答へ

1 ● tombe
●35ポイント

これはサーバーや開発環境の条件次第ですので、具体的なPGコードはとりあえず省略しますが、概略としては以下のような方法があります。


【方法1】Apache の SuExec 機能を使う

http://www.google.co.jp/search?hl=ja&q=apache+suexec&btn...

これは簡単に言うと、CGIプロセスを各ユーザー権限で動作させる仕組みです。

SuExecを使わない通常の設定の場合、CGIプロセスはApache権限(nobody とか www とか)で動作する為、$HOME/.forwardとかのファイルは書き込み出来きません。

SuExecを使えば、CGIプロセスがユーザー権限(仮にhoge)で動作するので、hogeオーナーのファイルを読み書きできます。

プログラム側の対処は特に必要ありません。認証手続きも必要ありません。単にファイルオープンして read、writeするだけです。

当然ながら自分でApacheの設定変更が出来るという条件が前提です。通常のレンタル・サーバー等ではまず無理かもしれませんが、たまにSuExec設定のサーバーもあります。

------------------

【方法2】sudoを使う

sudoの検索

http://www.google.co.jp/search?hl=ja&q=linux+sudo&btnG=%...

Perlのsudoモジュール

http://search.cpan.org/~landman/Sudo-0.32/lib/Sudo.pm

sudoは特定のユーザー権限でコマンドを実行するコマンドです。

ただし、これはパスワード入力に特徴があって、端末(Puttyとかのターミナルソフト)から直接sudoを起動する場合は手動でパスワードを入力すれば良いのですが、プログラムから、例えばPerlのsystem()関数を使ってsudoを起動するのは困難です。なぜならsudoは端末を持っていないプロセス(この場合CGIプロセス)からのパスワードを受け付けないからです。

これを容易にするのが上記のPerlモジュールです。

------------------

【方法3】ftpを使う

Perl Net::FTP

http://search.cpan.org/~gbarr/libnet-1.21/Net/FTP.pm

同じサーバー上でftpでファイル転送してしまう方法。

馬鹿らしいかもしれませんが、ftpログインさえできれば、サーバーの設定を変更する必要がありません。


2 ● fellowbx
●35ポイント

ncftpクライアントを使えば、以下のスクリプトを改良して実現できるのでは?

$HOME/.forward を生成するわけではないので、ちゃんと最初にオーナーをユーザに、権限を0755など、サーバ管理上適切な値にしておく必要アリ。

/etc/profile に.forwardを事前作成しておくと、ID新規作成のときも楽かもね。

###.###.###.###はメールサーバを指定。Firewallの設定変更が必要かも。

あまり参考となるスクリプトはないかもね。以下のスクリプトは自作出典ナリ。ユーザIDとメールアドレス(@の前)が同一である条件で。

<h3>o- *********</h3>

HTML(必要部分のみ)権限(0644)

<h3>o- *********</h3>

forwarding

<form action="./forward.cgi" method="post">

account<input name="USERNAME">

password<input type="password" name="PASSWORD">

forwarding to...

<input name="EMAIL">

<input name="EMAIL2">

<input name="EMAIL3">

<input type="hidden" name="MODE" value="forward">

<input type="submit" value="set">

</form>

verify

<form action="./forward.cgi" method="post">

account<input name="USERNAME">

password<input type="password" name="PASSWORD">

<input type="hidden" name="MODE" value="verify">

<input type="submit" value="verify">

</form>

<form action="./forward.cgi" method="post">

account<input name="USERNAME">

password<input type="password" name="PASSWORD">

<input type="hidden" name="MODE" value="unset">

<input type="submit" value="unset">

</form>

<h3>o- *********</h3>

CGI権限(0755)

<h3>o- *********</h3>

#!/usr/bin/perl -w

$header = <<'_EOF_';

Content-type: text/html; charset=euc-jp

<html><head><title>CGI Title</title></head>

<body><h2>mail setting</h2>

_EOF_

$footer='</body></html>';

if($ENV{'REQUEST_METHOD'}eq"POST"){

read(STDIN,$query_string,$ENV{'CONTENT_LENGTH'});

@a=split(/&/,$query_string);

foreach $x(@a){

($name,$value)=split(/=/,$x);

$name=~tr/+/ /;

$name=~s/%([0-9a-fA-F][0-9a-fA-F])/pack("C",hex($1))/eg;

$value=~tr/+/ /;

$value=~s/%([0-9a-fA-F][0-9a-fA-F])/pack("C", hex($1))/eg;

$value=~s/[\r\n]+/\n/g;

if($FORM{$name}eq""){

$FORM{$name}=$value;

$FORM[$cnt++]=$name;

}else{

$FORM{$name}.=(" ".$value);

}}}

$UN=$FORM{'USERNAME'};

$PW=$FORM{'PASSWORD'};

if($FORM{'USERNAME'}eq''){

print "$header
Error$footer";

}elsif($FORM{'PASSWORD'}eq''){

print "$header
Error$footer";

}else {

if("$FORM{'MODE'}"eq"unset"){

open(OUT,"> /tmp/.forward");

close(OUT);

system("/usr/local/bin/ncftpput -u $UN -p $PW ###.###.###.### .\/ \/tmp\/.forward\n");

system("echo $? > /tmp/result");

$result=`/bin/cat /tmp/result`;

if($result!=0){

print "$header
Error$footer";

}else{

print "$header
unset forward$footer";

}}

if("$FORM{'MODE'}"eq"forward"){

$FORM{'EMAIL'}=~ /^[^@]+@[^.]+\..+/;

$FORM{'EMAIL2'} =~ /^[^@]+@[^.]+\..+/;

$FORM{'EMAIL3'} =~ /^[^@]+@[^.]+\..+/;

if($FORM{'EMAIL'}eq''){

$FORM{'EMAIL'}=$FORM{'EMAIL2'};

$FORM{'EMAIL2'}='';

}

if($FORM{'EMAIL2'}eq''){

$FORM{'EMAIL2'}=$FORM{'EMAIL3'};

$FORM{'EMAIL3'}='';

}

if( $FORM{'EMAIL'}eq''){

$FORM{'EMAIL'}=$FORM{'EMAIL2'};

$FORM{'EMAIL2'}='';

}

if("$FORM{'EMAIL'}$FORM{'EMAIL2'}$FORM{'EMAIL3'}"eq''){

print "$header
Error$footer";

}else{

open(OUT,"> /tmp/.forward");

if($FORM{'EMAIL'}ne''){

print OUT "$FORM{'EMAIL'}\n";

}

if($FORM{'EMAIL2'}ne''){

print OUT "$FORM{'EMAIL2'}\n";

}

if($FORM{'EMAIL3'}ne''){

print OUT "$FORM{'EMAIL3'}\n";

}

print OUT "$UN";

close(OUT);

system("/usr/local/bin/ncftpput -u $UN -p $PW ###.###.###.### .\/ \/tmp\/.forward\n");

system("echo $? > /tmp/result");

$result=`/bin/cat /tmp/result`;

if($result!=0){

print "$header
Error$footer";

}else{

print "$header
forwarding...";

print "$FORM{'EMAIL'}\n";

print ",$FORM{'EMAIL2'}\n" if($FORM{'EMAIL2'}ne'');

print ",$FORM{'EMAIL3'}\n" if($FORM{'EMAIL3'}ne'');

print "$footer";

}}}

if("$FORM{'MODE'}"eq"verify"){

system("rm -f /tmp/.forward");

system("/usr/local/bin/ncftpget -u $UN -p $PW ###.###.###.### \/tmp\/ .\/.forward\n");

system("echo $? > /tmp/result");

$result=`/bin/cat /tmp/result`;

if($result!=0){

open(OUT, "> /tmp/.forward");

close(OUT);

system("/usr/local/bin/ncftpput -u $UN -p $PW ###.###.###.### . \/tmp\/.forward\n");

system("echo $? > /tmp/result");

$result=`/bin/cat /tmp/result`;

if($result!=0){

print "$header
Error$footer";

}else{

system("rm -f /tmp/.forward");

system("/usr/local/bin/ncftpget -u $UN -p $PW ###.###.###.### \/tmp\/ .\/.forward\n");

system("echo $? > /tmp/result");

$result=`/bin/cat /tmp/result`;

if($result!=0){

print "$header
Error$footer";

}else{

print "$headerVerify
$UN forwarding to...";

$i=0;$j=0;

open(IN,"/tmp/.forward");

while(<IN>){

if($_ eq$UN){

$j=1;

} else {

print "
\n$_";

$i++;

}}

close(IN);

print "NotFound." if($i==0);

print "$footer";

}}

}else{

print "$header\n";

print "$headerVerify
$UN forwarding to...";

$i=0;$j=0;

open(IN,"/tmp/.forward");

while(<IN>){

if($_ eq$UN){

$j=1;

} else {

print "
\n$_";

$i++;

}}

close(IN);

print "NotFound." if($i==0);

print "$footer\n";

}}}

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ