良い一日。 ここでそのような問題に直面しました-SQLクエリを通じて、PHPキャッシュをリセットします。 特定のディレクトリにある複数のファイルを削除するだけです。 入り口にあります:
- DBMS-PostgreSQL 9.3
- OS-Linux(Fedora、しかしポイントではない)
その結果、python + C + bashバンドル(すべてのビット)で解決策を得ました。 Unix系ではありませんが、誰かにとっては便利かもしれません。
PHPキャッシュ削除コマンドをbashスクリプトでラップし、新しい機能でさらに拡張することを考えています。 一般的に、目的のコマンドをパラメーターとして渡すとよいでしょう。 スクリプトは次のとおりです。
ここでは、関数(コマンドなど)のリストを含む配列を宣言し、転送されたコマンド(関数など)を呼び出す前に、リストにあるかどうかを確認します。 そうでなければ、悪いユーザーは
rm -rf ...のようなものをパラメーターとして渡すことができ、これは
evalで成功し
ます 。 このルートスクリプトの所有者を設定し(Apacheで十分ですが、注意を忘れずに拡張性を考えています)、スクリプトを実行します。
chown root:root sysutils chmod ugo+x sysutils
このスクリプトは、DBMSからC(PostgreSQLへの拡張機能を作成する必要があるため長い道のり)またはアンマネージスクリプト言語(plpython)から実行できます。 しかし、最初に考えてみましょう-DBMSからのスクリプトはpostgresユーザーの権限で実行され、(少なくとも)apacheのみがキャッシュを削除できます。 しかし、それは問題ではありません。SUIDフラグなどがあります。 しかし問題は、LinuxではスクリプトのSUIDフラグを設定できないことです(詳細は
こちら )。 むしろ、可能ですが、有効なユーザーIDは実際のユーザーIDと同じままです。 スクリプトを呼び出す小さなCプログラムを作成して、この制限を回避してみましょう。 彼女のコードは次のとおりです。
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> int main(int argc, char *argv[]) { setuid(0); char command[255]; if (argc == 2) { snprintf(command, 255, "/usr/local/bin/sysutils %s", argv[1]); system(command); } else { printf("USAGE: sysutils-core <command>\n"); } return 0; }
まず、有効なユーザーIDを設定し、次にパラメーター(必須コマンド)を渡してスクリプトを呼び出します。 プログラムをコンパイルし、SUIDフラグを設定します。
gcc -o sysutils-core sysutils-core.c chmod u+s sysutils-core
私たちはチェックします:
su postgres ./sysutils-core clear_cache
それでは、DBMSパートに移りましょう。
適切なデータベースでSQLコマンドを実行して、plpython3拡張機能(システムにプリインストールされている)をインストールします。
CREATE EXTENSION plpython3u;
または、コンソールを使用して:
createlang plpython3u -h localhost -U postgres testdb
キャッシュをリセットするDBMSの関数は次のようになります。
CREATE OR REPLACE FUNCTION clear_cache ( ) RETURNS void AS $BODY$ import os os.system("/usr/local/bin/sysutils-core __clear_cache") $BODY$ LANGUAGE plpython3u VOLATILE;
これは、clear_cacheパラメーターを指定したsysutils-core呼び出しです。 私たちはチェックします:
SELECT clear_cache ( );
必要に応じて、関数呼び出しはpostgres(アンマネージ言語で関数を作成できるのはこのユーザー)だけでなく、この場合、関数を作成するときにオプション
-SECURITY DEFINER (DBMSのSUIDに類似)を指定する必要があります。
以上です。 必要に応じて、渡す引数、新しいコマンドを追加し、一般にDBMSを介してLinuxサーバーを管理できます。 宿題にしましょう。
UPD :Cプログラムのより安全なバージョン(
execl経由):
非表示のテキスト #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> #include <error.h> #include <sys/wait.h> #include <errno.h> int main(int argc, char *argv[]) { setuid(0); if (argc == 2) { int status = 0; int pid = fork(); switch (pid) { case -1: printf("Fork sysutils process failed"); exit(1); case 0: execl("/bin/bash", "bash", "/usr/local/bin/sysutils", argv[1], NULL); default: wait(&status); } } else { printf("USAGE: sysutils-core <command>\n"); } return 0; }