cgiとホームディレクトリ

[上に] [前に] [次に]
羽崎 1999/05/15(土) 12:52:08
unixのホームディレクトリとCGI(Perlスクリプト?)の関係でいまいち理解していないので質問したいことがあります。
以下のスクリプトで

open(FILE, ">~/public_html/fuga.html");
@file = <FILE>;
close(FILE);
print "Content-type: text/html\n\n";
foreach (@file){
print;
}

("~"の正しいパスは"/home/hoge")
とした場合、あるユーザの"~/public_html/fuga.html"というパスにあるファイルを読み出して表示するというものですが、
/home/hoge/public_html/fuga.html
のファイルを読みに行っていません。
これはCGIがユーザ"hoge"として実行されていないからなのででしょうか?

羽崎 1999/05/15(土) 13:32:40
自己レスです。

× open(FILE, ">~/public_html/fuga.html");
○ open(FILE, "~/public_html/fuga.html");

あと、CGIはnobodyとして実行されるというふうな理解でいいのか、
CGIで作成されたものは所有者がnobodyになるのか、よくわかりません。どうぞよろしくお願いします。

\n 1999/05/15(土) 15:25:56
実際にファイルを生成してそのファイルのステータスを見るのでは
だめですか?
そうでなければ、print getpwuid($>)で実行ユーザーが取得できます。

羽崎 1999/05/16(日) 00:56:46
リプライありがとうございます。
なるほど、getpwuidで確認できました。
どうやらcgiはnobody権限で動いているようでした。

"~"(チルダ)ではシェルのようにホームディレクトリを表せないんですね。

B-Cus 1999/05/16(日) 01:09:13
> "~"(チルダ)ではシェルのようにホームディレクトリを表せないんですね。

想像ですが、perlはopen(...)内がコマンドとして解釈できる場合だけ
shに処理をまかせます。shは ~ を展開してくれますが、perl自身は ~ の
展開を行いません。ですから、shに処理が渡れば ~ はホームディレクトリに
展開されます。

例えば
 open(IN,"~/file");
はダメですが、
 open(IN,"cat ~/file|");
は展開されます。

> どうやらcgiはnobody権限で動いているようでした。

まぁ、こういう場合は、CGIでは ~/ は /home/nobody/ に
展開されるでしょうから、~ を使えるメリットは減りますけどね。

B-Cus 1999/05/16(日) 04:19:21
> ~/ は /home/nobody/ に展開されるでしょうから

あ、これ嘘。

普通、nobodyのホームディレクトリは /nonexistent や / に
なっているので(/etc/passwd で定義されている)、/home/nobody には
展開されません。

羽崎 1999/05/17(月) 01:33:50
>open(...)内がコマンドとして解釈できる場合だけ
>shに処理をまかせます
なるほど。Perlが処理する場合、誰が処理するってことにかかわらずshに渡すわけですね。

> open(IN,"cat ~/file|");
>は展開されます。
ということは、telnetで同じスクリプトを実行したとき、~/は/home/hogeと展開されるのが正しい動きでしょうか?

B-Cus 1999/05/17(月) 17:28:59
> telnetで同じスクリプトを実行したとき、
> ~/は/home/hogeと展開されるのが正しい動きでしょうか?

 open(IN,"~/file");
は展開されませんが、
 open(IN,"cat ~/file|");
は展開されます。

ちゃわ [E-Mail] 1999/05/17(月) 21:30:07
・~(チルダ)の扱いについて

/etc/passwdファイルで fuga というユーザーが登録されている場合、
~ユーザー名 ( ~fuga ) で、ユーザー fuga のホーム・ディレクトリを指します。
もし fuga のホーム・ディレクトリが /home/hoge/fuga であれば、
~fuga は '/home/hoge/fuga' という文字列に展開されます。

・nobody について

これはサーバーの設定によって決まるものです。
サーバーを立ち上げるときの設定ファイルに、/etc/passwd に登録されている
どのユーザーでサーバーのプロセスを起動するかという項目があります。
一般的なサーバーでは、ここを nobody に設定していることが多いのです。
CGIはサーバーのプロセスから子プロセスとして起動されますが、
サーバー・プロセス自体が nobody の所有になっているため、そのプロセスが
新たに生成した子プロセス(CGI)も、親と同じ実行ユーザー nobody
という環境を引き継ぎます。それで、一般のサーバーでは nobody という
実行ユーザーでプロセスが動くわけです。あくまでもこれは、そうしている
サーバーが多いというだけの話しです。

・~nobody について

大抵のUNIXでは、nobody のホーム・ディレクトリは / となっています。
この場合 ~nobody は '/' という文字列に展開されます。

羽崎 1999/05/18(火) 01:00:06
なるほど、納得しました。>B-Cusさん、ちゃわさん

>これはサーバーの設定によって決まるものです。

とすれば、サーバの設定次第でnobodyでなくユーザの権限で実行されるサーバもありというわけですね。(webserverの仕様書を読んだことがない上での発言お許しを)

> ~nobody は '/' という文字列に展開されます。

とすると ~ は
open(FILE, "~/public_html/fuga.html");
の場合
open(FILE, "/public_html/fuga.html");
と同じ事となるわけですね。

B-Cus 1999/05/18(火) 02:04:10
> とすれば、サーバの設定次第でnobodyでなくユーザの権限で実行されるサーバも
> ありというわけですね。

例えば apacheならcgiwraperやsuExecを仕込むことで、
CGIやSSIのが各ユーザ権限で動きます。

> webserverの仕様書を読んだことがない上での発言お許しを

ここらへんの動作についての仕様書は存在しません。
RFCで決まっているのはHTTPの仕様のみで、プロセスが
どの権限で動くかは各ソフトウェアの実装次第です。


> open(FILE, "~/public_html/fuga.html");
> の場合
> open(FILE, "/public_html/fuga.html");
> と同じ事となるわけですね。

違います。この場合perlはshを使わないので ~は展開されず、
カレントディレクトリにある ~ というディレクトリの下を
見にいきます。
 mkdir \~
 mkdir \~/public_html
 echo hoge > \~/public_html/fuga.html
などと ~ をエスケープしながらファイルを作成すると、そのファイルを
読みにいくことがわかるでしょう。


一方、
 open(FILE,"cat ~/public_html/fuga.html");
なら ~ は展開されますが、以下のパターンが考えられます。

(1) もし nobody 権限で動いていて、nobodyのホームディレクトリが / なら
 open(FILE,"cat //public_html/fuga.html");
と展開されます。// は / と同じ意味なので、結局 cat は
 /public_html/fuga.html
を読もうとします。

(2) もし nobody 権限で動いていて、nobodyのホームディレクトリが /nonexistent なら
 open(FILE,"cat /nonexistent/public_html/fuga.html");
と展開されます。

(3) もし各ユーザの権限で動いていたら、
 open(FILE,"cat /home/user/public_html/fuga.html");
などと展開され、羽崎さんの希望通りの動作をします。

羽崎 1999/05/18(火) 22:05:20
[[解決]]
失礼しました。

>ここらへんの動作についての仕様書は存在しません。
>RFCで決まっているのはHTTPの仕様のみで、プロセスが
>どの権限で動くかは各ソフトウェアの実装次第です。

HTTP1.0の(かの有名なRFC日本語化サイトの)日本語訳の仕様書は少々読んだことがありますが、そういった実装の部分での仕様には触れていませんでしたね。

つまり、nobody権限で動いているサーバのCGIで~を使っても
そのCGIスクリプトの所有者のホームディレクトリは表さない、ということですね。つまり、パスははしょらずちゃんと書け、ということですね。^^;

[上に] [前に] [次に]