|
> 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が使われるのかも しれません。 |
|
えぇぇぇぇぇぇぇぇ!!!!!!??????? なんでぇ??? #すいません無駄な行を書いてしましました。(^^ゞ なんか、うちの環境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を有効にすると、サーバーエラー になります。 コマンドラインから実行すると、正常なんですが...。 #なぜ???? |
|
うちでも同じです。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: と吐いてくれるはずです。 |
|
>先頭で $|=1 とすればいいでしょう。 なるほど、これ($|=1)も関係あったんですね。 う〜ん、もっと詳しく検証せねば。 もうちょっと探ってみます。 |
|
一般的には、以下のの方法でデバッグすると、大抵の場合解決すると思います。 #!/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になりました。 |
|
大変お騒がせしている、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型? |
|
> ファイルハンドルを指定しなくとも最後に openしたハンドルのみ > クローズされると、思っていたのですが。suidな時、STDOUTまで > クローズされませんか? suidかどうか/httpd経由かコマンドラインか に関わらず、STDOUTが クローズされました。そもそもcloseってファイルハンドルを省略 すべきでないし、仮に省略した場合はselectで指定されたファイル ハンドル(デフォルトはSTDOUT)がクローズされるんじゃないですかね? # perl4、perl5.004で試しました。 > ところで、wrapper.cgiでのurl指定方法のwrapper.cgi/hoge.cgi > は、知ってはいたのですがどういう動作になるのですか? print文を埋め込んで試してみませう ;-) |
|
>suidな時、STDOUTまでクローズされませんか? ホントだぁ...これまた私の勘違い。 いままで作ったスクリプトを見直したら、ちゃんとやってました。 意識していたわけではなく、性格的な問題?からそうしていたの ですが、これって案外重要だったのですね。 この件でのスクリプトでの試験では、安易にそうしていただけでし た。#お恥ずかしい。(*^_^*;;; closeのみだとSTDOUTまでクローズされ、結果スクリプトが終了して しまうのですね。 >パスが通って無いのが原因と判明しました。 よく考えたら、スクリプト内で$ENV{PATH}=''としてるのに、何を 言ってるんでしょう私は。(; ;) でもなんで、$ENV{PATH}=''としなければいけないのでしょうか。 新たな疑問! #まるで小学生のガキが、なぜなぜ攻撃してるみたいですが..(^^ゞ #最近、私を含め周りにUNIX信者が増えている模様です。 #だって面白いんだもん。 >print文を埋め込んで試してみませう ;-) すいません、オバカでよく分からないのですが具体的にどうすれば 私にも理解できるでしょうか。 ↑完全に開きなおってるかもしれない(^_^)V これだけいろいろ御世話になっているので、何かお礼がしたいとこ ろですが、なにか出来る事が有れば言って下さい。 と、いっても何が出来るわけでは無いし....でも気持ちだけは有り ます。(本気度=120%) |
|
> すいません、オバカでよく分からないのですが具体的にどうすれば > 私にも理解できるでしょうか。 何を知りたいのかわからないので、全部は説明したくないです(結構な量になるので)。 何を知りたいのでしょうか? できれば open(EXEC,"| .$ENV{PATH_INFO} 2>&1"); というのを書いたのだから、「とりあえずPATH_INFOの値を見てみる」 くらいは試してください。 > でもなんで、$ENV{PATH}=''としなければいけないのでしょうか。 一言で言えば「汚れている」からです。消す必要はなくて、PATHを 再設定すればよかったですね。長くなるので青ラクダ本 P.409 参照。 別に質問するなってわけじゃないですけど、自分で調べる努力は必要です。 それでもわからなかったらどんどん質問すればいいですけど、その際でも 極限まで発生条件を切り詰めた上で、 「何がわからないか」「どのような状況で調べたのか」 などを書かないと、結局 回答者側が苦労するハメになります。 |
|
よかったやっと見れるようになった。(^^ゞ う〜んすいませんです。 >> すいません、オバカでよく分からないのですが具体的にどうすれば >> 私にも理解できるでしょうか。 > 何を知りたいのかわからないので、全部は説明したくないです(結構な量になるので)。 >「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の様な指定方法は、 掲示板等では話題としては知っていましたが、具体的な内容まではまだ 未解析でした、すいませんです。 |
|
> よかったやっと見れるようになった。(^^ゞ サーバの定期メンテがあって、落ちてたようです。 そもそもの > ところで、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に値が入る、っていうくらいです。 という解説でいいですか? どうもそういうことを聞きたいんじゃ ないような気もするんですが、聞きたいことと違っていたら 「何が知りたいか」を書いてください。 |
|
>そもそもの 大変申し訳有りませんでした。 言葉が足りませんでしたね。 今までの流れから、「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} と返り意味が分かりません。 と、こんなところです。 いろいろ他にもありますが、これから書込みの際は十分吟味した後 に書込みしたいと思います。 今後もよろしくお願いいたします。 |
|
> デバック目的だけの機能では無いだろうし、本来の目的は何だろう 「なぜその機能があるのか」と考えるのは、「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 というスクリプトを実行しているだけですね。 |
|
なるほど、やっと理解できました。 68Userさんがわからないと言っていた事や、自分の勘違いが。 理解したと思っていた事が、全然理解できていなかったのですね。 やはり他の仕事の片手間のように勉強しているのと、基礎からしっか り勉強している人にはかないませんネ。 ちょっとプログラミングに深入りしすぎたかも知れません、web上で よく見かけるプログラム程度なら書けるかもしれませんが、システム や応用した機能みたいな部分(少なくとも私から見ると)は、ちゃんと 勉強しないと難しすぎます。 最近、業界では有名(らしい)なプログラマー人とファイルロックの 事で話しをする機会がありましたが、私とは基礎概念が違いました。 もう少し、時間をかけて基礎的な部分から修行したいと思います。 wrapper.cgi、ありがとうございました。 |
|
UNIXは初心者です、ここで質問して良いかもわかりませんが、よろしければお教え下さい。 OSはだいぶ古いSONY製のNEWS−OSというのを使用しています。相当古いマシンなので、また UNIXなのでちょっと恐くてさわれないのですが、基本的なコマンドは少し勉強しました。 前置きが長くなってしまいましたが・・・ハードディスクの空き容量を調べたいと思うのですが、どの ようなコマンドを使えば良いのかよくわかりませんでした。どうぞ、お教え下さい。そういうコマンドとか は無いのでしょうか? |
|
NEWS-OSはよく知りませんが、df -kで Filesystem 1K-blocks Used Avail Capacity Mounted on /dev/sd0s1a 118959 25837 83606 24% / などという表示が出るんじゃないでしょうか。これだと 118M中 25M(全体の24%)を使用中ってことです。 |
|
はじめまして。他にはない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ファイルが見れなくなります。 どうぞお試しくださいませ。(知ってたらごめんなさい。(汗)) |