68user's page 掲示板

Prev< No. 239〜255> Next  [最新発言に戻る] [過去ログ一覧]
No. 239 # 68user 1999/03/29 (月) 13:46
> forkされたプロセスでは、再びnobodyに戻ってしまう事です。
やはりうちではそうはなりませんでした。
    #!/usr/local/bin/perl
    $|=1;
    $ENV{PATH}="";
    print "Content-type: text/plain\n\n";
    open(IN,"/bin/cat /etc/master.passwd");
    print <IN>;
    if ( fork ){
        system("/usr/bin/id");
    } else {
        system("/usr/bin/id");
    }
というスクリプトをowner=root、permission=4755にして、コマンドライン、
httpd 経由両方で動くことを確認しました。600な/etc/master.passwdの
中身は表示されましたし、idの結果は
    uid=65534(nobody) euid=0(root)
となりました。forkしても実効ユーザはrootのままでした(まぁ system を
実行するってことは、fork/execしてるわけですが)。

なお、PATHをクリアしないと
    Insecure $ENV{PATH} while running setuid at ./hoge.cgi line xx.
となりました。

あ、ファイルを作成してみるのを忘れてた。もしかしたらそのとき作成した
ファイルのオーナーは実効ユーザIDでなく、実ユーザIDが使われるのかも
しれません。

No. 240 # M.Masuda 1999/03/29 (月) 15:19
えぇぇぇぇぇぇぇぇ!!!!!!???????
なんでぇ???
#すいません無駄な行を書いてしましました。(^^ゞ

なんか、うちの環境system関数が変です。
suidを立てずに、普通に755のパーミッションです。

#!/usr/bin/perl
print "Content-type: text/plain\n\n";

print "Script Start\n";

if(system("")){
                print "Done..\n";
}else{
                print "NG! \n";
}

#system("ls -l 2>&1");

print "End Script\n";

2つめのsystem関数(system("ls -l 2>&1")の部分)を、コメントア
ウトした時としない時の結果の結果を教えてくれませんか?

うちの環境では、2つ目のsystemを有効にすると、サーバーエラー
になります。
コマンドラインから実行すると、正常なんですが...。
#なぜ????

No. 241 # 68user 1999/03/29 (月) 15:39
うちでも同じです。print文がバッファリングされた
状態でsystemの結果が先に表示されてるのでしょう。
先頭で $|=1 とすればいいでしょう。

httpdがログ(/var/log/httpd-error.logなど)に
    [Mon Mar 29 15:32:06 1999] [error] malformed header from script. Bad header=total 1406:
と吐いてくれるはずです。

No. 242 # M.Masuda 1999/03/29 (月) 15:59
>先頭で $|=1 とすればいいでしょう。
なるほど、これ($|=1)も関係あったんですね。
う〜ん、もっと詳しく検証せねば。

もうちょっと探ってみます。

No. 243 # 68user 1999/03/29 (月) 16:11
一般的には、以下のの方法でデバッグすると、大抵の場合解決すると思います。
    #!/usr/local/bin/perl
    $|=1;
    print "Content-type: text/plain\n\n";
    open(EXEC,"| .$ENV{PATH_INFO} 2>&1");
    while (<STDIN>){
        print EXEC;
    }
という内容の wrapper.cgi を作ってください。hoge.cgiの動作チェックをしたいなら
    /~user/cgi-bin/wrapper.cgi/hoge.cgi

    /~user/cgi-bin/wrapper.cgi/hoge.cgi?data

などというURLで実行してください。そしたら、
    - $|=1を付けないと Content-type より ls の結果が先に出力されてること
    - system や open(COMMAND,"command |") の中で
            cat: /etc/master.passwd: Permission denied
        などのエラーが起こっていること

がわかるでしょう。一連の環境変数(QUERY_STRINGなど)は引き継がれますし、
POSTの場合のデータの受け渡しもできます。

というわけで、CGIが動かなかったら、まずはこれでチェックして
みてください。

あと
> もしかしたらそのとき作成したファイルのオーナーは実効ユーザIDでなく、
> 実ユーザIDが使われるのかもしれません。
は、suidなperlスクリプト中で新規ファイルを作成した場合は
perlスクリプト所有者権限で動きました。つまり
    uid=65534(nobody) euid=0(root)
の場合、新規ファイルのオーナーはrootになりました。

No. 244 # M.Masuda 1999/03/29 (月) 18:09
大変お騒がせしている、M.Masudadです。
こんどこそやっと解決マークがつけられそうです。(^^ゞ

>なんか、うちの環境system関数が変です。
この件に関しては、原因はsystem関数実行時に、指定コマンドの
パスが通って無いのが原因と判明しました。
フルパス指定するとsystem関数はちゃんと動きました。
今までsystemでコマンドを使ったサーバーのnobodyにはたまたま
コマンドのパスが通っていただけみたいですね。
#いままでぜんぜん気が付かなかった....。
#なんか一人で大騒ぎしてますね。←私(>_<)

まとめるとsuidスクリプトを、実行したい権限のオーナーにして
chmod 4755 を設定。
$|=1; でバッファリングを止めて、systemで使うコマンドはフルパ
スで指定するか、パスをあらかじめ指定しておく。

closeはどうですか?、ファイルハンドルを指定しなくとも最後に
openしたハンドルのみクローズされると、思っていたのですが。
suidな時、STDOUTまでクローズされませんか?

$|=1; は、保険と考えて全てのperlスクリプトに入れた方が、悩む
回数が減りそうですね。
やはりperlもosと密接に関係しているのが改めて分かりました。
こういうケースは、UNIXのシステムを十分理解していないとデバック
しきれなかったかも知れないですね。

http://www.excel-net.co.jp/~masuda/su/
にある su.cgi に試験スクリプトを置きました。
これで見ると、だいぶ嘘ついてましたね。(^^ゞ
今までの件が判明しました。

実験に付き合ってもらってすいませんでした。
wrapper.cgiもありがとうございます。
非常に勉強になりました。m(_ _)m

ところで、wrapper.cgiでのurl指定方法のwrapper.cgi/hoge.cgi
は、知ってはいたのですがどういう動作になるのですか?

># だって、「いいページだ」と書かれるより、「ひどいページだ」と
># 書いてある方がうれしいから。悔しいので、ページを よりよいものに
># しよう、という気が起こりますよね。
いや〜こういう前向きな考え方をできる人って、今時なかなかいな
いですよ。
#68UserさんってもしかしてA型?

No. 245 # 68user 1999/03/29 (月) 20:44
> ファイルハンドルを指定しなくとも最後に openしたハンドルのみ
> クローズされると、思っていたのですが。suidな時、STDOUTまで
> クローズされませんか?
suidかどうか/httpd経由かコマンドラインか に関わらず、STDOUTが
クローズされました。そもそもcloseってファイルハンドルを省略
すべきでないし、仮に省略した場合はselectで指定されたファイル
ハンドル(デフォルトはSTDOUT)がクローズされるんじゃないですかね?
# perl4、perl5.004で試しました。

> ところで、wrapper.cgiでのurl指定方法のwrapper.cgi/hoge.cgi
> は、知ってはいたのですがどういう動作になるのですか?
print文を埋め込んで試してみませう ;-)

No. 246 # M.Masuda 1999/03/29 (月) 23:01
>suidな時、STDOUTまでクローズされませんか?
ホントだぁ...これまた私の勘違い。
いままで作ったスクリプトを見直したら、ちゃんとやってました。
意識していたわけではなく、性格的な問題?からそうしていたの
ですが、これって案外重要だったのですね。
この件でのスクリプトでの試験では、安易にそうしていただけでし
た。#お恥ずかしい。(*^_^*;;;

closeのみだとSTDOUTまでクローズされ、結果スクリプトが終了して
しまうのですね。

>パスが通って無いのが原因と判明しました。
よく考えたら、スクリプト内で$ENV{PATH}=''としてるのに、何を
言ってるんでしょう私は。(; ;)
でもなんで、$ENV{PATH}=''としなければいけないのでしょうか。
新たな疑問!
#まるで小学生のガキが、なぜなぜ攻撃してるみたいですが..(^^ゞ
#最近、私を含め周りにUNIX信者が増えている模様です。
#だって面白いんだもん。

>print文を埋め込んで試してみませう ;-)
すいません、オバカでよく分からないのですが具体的にどうすれば
私にも理解できるでしょうか。
↑完全に開きなおってるかもしれない(^_^)V

これだけいろいろ御世話になっているので、何かお礼がしたいとこ
ろですが、なにか出来る事が有れば言って下さい。
と、いっても何が出来るわけでは無いし....でも気持ちだけは有り
ます。(本気度=120%)

No. 247 # 68user 1999/03/30 (火) 04:14
> すいません、オバカでよく分からないのですが具体的にどうすれば
> 私にも理解できるでしょうか。
何を知りたいのかわからないので、全部は説明したくないです(結構な量になるので)。
何を知りたいのでしょうか? できれば
    open(EXEC,"| .$ENV{PATH_INFO} 2>&1");
というのを書いたのだから、「とりあえずPATH_INFOの値を見てみる」
くらいは試してください。

> でもなんで、$ENV{PATH}=''としなければいけないのでしょうか。
一言で言えば「汚れている」からです。消す必要はなくて、PATHを
再設定すればよかったですね。長くなるので青ラクダ本 P.409 参照。

別に質問するなってわけじゃないですけど、自分で調べる努力は必要です。
それでもわからなかったらどんどん質問すればいいですけど、その際でも
極限まで発生条件を切り詰めた上で、
    「何がわからないか」「どのような状況で調べたのか」
などを書かないと、結局 回答者側が苦労するハメになります。

No. 248 # M.Masuda 1999/03/30 (火) 18:31
よかったやっと見れるようになった。(^^ゞ

う〜んすいませんです。
>> すいません、オバカでよく分からないのですが具体的にどうすれば
>> 私にも理解できるでしょうか。
> 何を知りたいのかわからないので、全部は説明したくないです(結構な量になるので)。

>「print文を埋め込んで試してみませう ;-)」
この意味そのものが分からなかったのです。m(_ _)m

この文がどういう意味で書いたのか、何を言いたかったのか、
と言う意味で、単純に私の日本語理解度が足りないための質問でした。

> 何を知りたいのでしょうか? できれば
>  open(EXEC,"| .$ENV{PATH_INFO} 2>&1");
>「とりあえずPATH_INFOの値を見てみる」
> くらいは試してください。

setコマンドで環境変数を見てみましたが PATH_INFOは設定されてい
ませんでした。

私なりに理解できた部分は open(EXEC,"| .$ENV{PATH_INFO} 2>&1");
.$ENV{PATH_INFO} の実行結果の標準&エラーを、openして標準入力
から読込み、表示させているという事位ですが。

前に使い方を、教えてもらい(wrapper.cgi/script.cgi)このような
URL指定でscriptcgiを実行すると、コマンドラインでの結果の様な表示に
なりました。


まず最初に、wrapper.cgi/script.cgi この様な指定をすると(URLで)
httpdはどういう事を行うのでしょうか?
予想1:
$ENV{PATH_INFO}には、コマンドでの引数に当たるものが代入される?

予想2:
最初に出現したwrapper.cgiの引数に、script.cgiを与えて実行する?

$ENV{PATH_INFO}この環境変数自体が、いつどのように設定されるのかが
解からないので、動作の結果から推測だけですが....
スクリプトやコマンドの実行時に、コマンドラインでの引数を指定する
のと同じような動作になるのでしょうか?

仮に上記の予想が合っているとして、「print文を埋め込んで試してみませう ;-)」
この文は、どこにprint文を入れろと言っているのかが、解からなかったのです。

私にとってまだ頭の中では、wrapper.cgi/script.cgiの様な指定方法は、
掲示板等では話題としては知っていましたが、具体的な内容まではまだ
未解析でした、すいませんです。

No. 249 # 68user 1999/03/31 (水) 00:00
> よかったやっと見れるようになった。(^^ゞ
サーバの定期メンテがあって、落ちてたようです。

そもそもの
> ところで、wrapper.cgiでのurl指定方法のwrapper.cgi/hoge.cgi
> は、知ってはいたのですがどういう動作になるのですか?
からは、「何をわかっていて、何がわからないのか」が伝わって
こないのですよ。

> 私なりに理解できた部分は open(EXEC,"| .$ENV{PATH_INFO} 2>&1");
> .$ENV{PATH_INFO} の実行結果の標準&エラーを、openして標準入力
> から読込み、表示させているという事位ですが
でしょ? こちらもそれくらいはわかっているだろう、とは思うわけで、
一体何を説明すればいいのかわからんのです。ですが、例えば
    「PATH_INFOというのはいつどこで誰が設定してくれるのか」
という質問なら答えられるわけです。

wrapper.cgi/hoge.cgi にアクセスすると、
    ・apache が PATH_INFO に /hoge.cgi を設定する
    ・apache が wrapper.cgiを実行する
です。それだけ。

別に特別な動作をするわけでなく、wrapper.cgi?hoge.cgi と
似たようなものだと思ってください。?を/に変えると
QUERY_STRINGでなくPATH_INFOに値が入る、っていうくらいです。

という解説でいいですか? どうもそういうことを聞きたいんじゃ
ないような気もするんですが、聞きたいことと違っていたら
「何が知りたいか」を書いてください。

No. 250 # M.Masuda 1999/03/31 (水) 15:12
>そもそもの
大変申し訳有りませんでした。
言葉が足りませんでしたね。

今までの流れから、「print文を埋め込んで試してみませう」
の所に何らかの意味合いが有ると思い、その意味合いを聴く為
あのような表現となりました。

それとは別に、最近の私の書込みも自分の中での疑問が次々に
解けていく快感に、つい調子に乗ってしまいフリートークBB
Sの様な書込みをしてしまったことを、少々反省しています。

今回の場合は、解からないところ(自分の中での疑問点だった複
数箇所)が、同時に提示されたので私もどう理解を進めていけば
いいのかが解かりませんでした。

>極限まで発生条件を切り詰めた上で
そうですね、これはデバックやコーディングの上で大事な事で
すね。
自分で解決する努力がすこし足りなかったですね。
というより本業の作業の間に行っている事なので、手抜きして
いたのは事実ですね、反省してます。

>「何が知りたいか」を書いてください。
そうですね、デバック用に教えて下さったwrapper.cgiのコード
の中には、解からない事が沢山ありますが、本来はオライリーの
動物シリーズを揃えて自分で調べればすむ事かも知れませんが、

>wrapper.cgi/hoge.cgi にアクセスすると、
> ・apache が PATH_INFO に /hoge.cgi を設定する
> ・apache が wrapper.cgiを実行する
という機能が何の目的でapacheに実装されているのか?
デバック目的だけの機能では無いだろうし、本来の目的は何だろ
う、というのがあります。

それから、基本的な動作を完全に理解しているわけでは無いので、
open(EXEC,"| .$ENV{PATH_INFO} での .$ENV{PATH_INFO}の記述が
よく分かりません。
open(HANDLER,"shellcommand")とした時は""で囲まれた部分は、
シェルでの動作と、全く同じと考えていいのでしょうか。

そうするとPerlだと変数を結合するためのピリオドが、シェルの
場合頭にピリオドが付くと何を表すのか。
ちなみにecho `.$ENV{PATH}` としましたが、
./home/masuda/.bashrc{PATH}
と返り意味が分かりません。
と、こんなところです。

いろいろ他にもありますが、これから書込みの際は十分吟味した後
に書込みしたいと思います。
今後もよろしくお願いいたします。

No. 251 # 68user 1999/04/01 (木) 20:52
> デバック目的だけの機能では無いだろうし、本来の目的は何だろう
「なぜその機能があるのか」と考えるのは、「C言語にはなぜ構造体があるのか」
というのと同じで、結局想像するしかないと思います。

でも、なぜ僕が wrapper.cgi?file=hoge.cgi(A) でなく wrapper.cgi/hoge.cgi(B)
という引数の取り方をしたのかは説明できます。

hoge.cgiが ?data=content などと、GET方式でデータを取得する
CGIだった場合、(A)より(B)の方が hoge.cgiに与える影響が少なく、
さらに wrapper.cgi 自体のコードも短くなるからです。

あと推測するに、ユーザにCGIであることを意識させない、という
のもあるでしょう。例えばcgiwrapは
    /cgi-bin/cgiwrap/~username/hoge.cgi
というURLでアクセスすることで、所有者権限でCGIを実行できます。
    /cgi-bin/cgiwrap?user=username&cgi=hoge.cgi
だったとしたら…思いつく限りではSave Asでファイルをセーブした際、
全てのCGIプログラムはcgiwrapというファイル名で保存されるでしょう。

ついでに言えばディレクトリのような階層構造を、素直な形で表現できます。
例えば http://www.freebsd.org/cgi/cvsweb.cgi など。

> そうするとPerlだと変数を結合するためのピリオドが、シェルの
> 場合頭にピリオドが付くと何を表すのか。
そういう場合にprint文で値を表示してみてほしいわけです。例えば
    > open(EXEC,"| .$ENV{PATH_INFO} 2>&1");
の前に
    print "PATH_INFO = $ENV{PATH_INFO}\n";
と書いたとすれば、$ENV{PATH_INFO} eq "/hoge.cgi"であることが
わかるでしょう。ならば、".$ENV{PATH_INFO}" eq "./hoge.cgi" と
なります(これに確信がもてなければ print ".$ENV{PATH_INFO}\n";
を挿入してください)。で、「./hoge.cgi」とは何かと言うと、カレント
ディレクトリにある hoge.cgi というスクリプトを実行しているだけですね。

No. 252 # M.Masuda 1999/04/01 (木) 23:53
なるほど、やっと理解できました。
68Userさんがわからないと言っていた事や、自分の勘違いが。

理解したと思っていた事が、全然理解できていなかったのですね。
やはり他の仕事の片手間のように勉強しているのと、基礎からしっか
り勉強している人にはかないませんネ。

ちょっとプログラミングに深入りしすぎたかも知れません、web上で
よく見かけるプログラム程度なら書けるかもしれませんが、システム
や応用した機能みたいな部分(少なくとも私から見ると)は、ちゃんと
勉強しないと難しすぎます。

最近、業界では有名(らしい)なプログラマー人とファイルロックの
事で話しをする機会がありましたが、私とは基礎概念が違いました。

もう少し、時間をかけて基礎的な部分から修行したいと思います。
wrapper.cgi、ありがとうございました。

No. 253 # Tetsu [E-mail] 1999/04/07 (水) 15:31
    UNIXは初心者です、ここで質問して良いかもわかりませんが、よろしければお教え下さい。
OSはだいぶ古いSONY製のNEWS−OSというのを使用しています。相当古いマシンなので、また
UNIXなのでちょっと恐くてさわれないのですが、基本的なコマンドは少し勉強しました。

  前置きが長くなってしまいましたが・・・ハードディスクの空き容量を調べたいと思うのですが、どの
ようなコマンドを使えば良いのかよくわかりませんでした。どうぞ、お教え下さい。そういうコマンドとか
は無いのでしょうか?

No. 254 # 68user 1999/04/07 (水) 17:58
NEWS-OSはよく知りませんが、df -kで
    Filesystem 1K-blocks Used Avail Capacity Mounted on
    /dev/sd0s1a 118959 25837 83606 24% /
などという表示が出るんじゃないでしょうか。これだと
118M中 25M(全体の24%)を使用中ってことです。

No. 255 # チャパ王 1999/04/09 (金) 19:20
はじめまして。他にはないCGIスクリプトばかりで大変助かっています。
それでですが、.htaccessで
<files browser.log>
deny from all
</files>
<files referer.log>
deny from all
</files>
    :
    :
というような設定がありますが、
<files *.log>
deny from all
</files>
<files *.dat>
deny from all
</files>
とやるだけで全ての***.log、***.datファイルが見れなくなります。
どうぞお試しくださいませ。(知ってたらごめんなさい。(汗))

Prev< No. 239〜255> Next  [最新発言に戻る] [過去ログ一覧]