接続が確立されたあと、サーバーはアクセス制御のステージ 2 に入ります。接続を介してユーザーが発行する各リクエストに対し、サーバーはユーザーが実行する操作を判別し、その操作を行う十分な権限をユーザーが持つかどうかを検査します。ここで、付与テーブルの権限カラムが役立ちます。これらの権限は、user
、db
、tables_priv
、columns_priv
、または procs_priv
テーブルから取得される可能性があります。(それぞれの付与テーブルにあるカラムの一覧を示す、セクション6.2.2「権限システム付与テーブル」を参照すると役立つことがあります。)
user
テーブルは、ユーザーにグローバルに割り当てられ、デフォルトのデータベースに関係なく適用される権限を付与します。たとえば、user
テーブルによってユーザーに DELETE
権限が付与された場合、そのサーバーホスト上のあらゆるデータベースのあらゆるテーブルの行を削除できてしまいます。user
テーブルの権限は、データベース管理者などの権限を必要とするユーザーに対してのみ付与するのが賢明です。ほかのユーザーについては、user
テーブルのすべての権限を 'N'
に設定しておき、具体的なレベルでのみ権限を付与するようにします。特定のデータベース、テーブル、カラム、またはルーチンに対して権限を付与することができます。
db
テーブルは、データベース固有の権限を付与します。このテーブルのスコープカラムの値は、次の形式を取ることができます。
ブランクの
User
値は匿名ユーザーに一致します。ブランク以外の値は文字どおりに一致し、ユーザー名にワイルドカードはありません。Host
およびDb
カラム内でワイルドカード文字「%
」および「_
」を使用することができます。これらはLIKE
演算子で実行されるパターンマッチング演算と同じ意味を持ちます。権限を付与するときにいずれかの文字を文字どおりに使用する場合、文字をバックスラッシュでエスケープする必要があります。たとえば、データベース名の一部としてアンダースコア文字 (「_
」) を含めるには、GRANT
ステートメント内でこれを 「\_
」 と指定します。'%'
またはブランクのHost
値は、「任意のホスト」を意味します。'%'
またはブランクのDb
値は、「任意のデータベース」を意味します。
サーバーは user
テーブルを読み取るのと同時に、db
テーブルをメモリーに読み取ってソートします。サーバーは、Host
、Db
、および User
スコープカラムに基づき db
テーブルをソートします。user
テーブルと同じように、ソートでは、もっとも具体的な値が最初に配置され、もっとも具体的でない値が最後に配置され、サーバーが一致するエントリを参照するときは、見つかった最初の一致が使用されます。
tables_priv
、columns_priv
、および procs_priv
テーブルは、テーブル固有、カラム固有、およびルーチン固有の権限を付与します。これらのテーブルのスコープカラムの値は、次の形式を取ることができます。
Host
カラム内でワイルドカード文字「%
」および「_
」を使用することができます。これらはLIKE
演算子で実行されるパターンマッチング演算と同じ意味を持ちます。'%'
またはブランクのHost
値は、「任意のホスト」を意味します。Db
、Table_name
、Column_name
、およびRoutine_name
カラムは、ワイルドカードを含めたり、ブランクにしたりすることができません。
サーバーは、Host
、Db
、および User
カラムに基づき、tables_priv
、columns_priv
、および procs_priv
テーブルをソートします。これは db
テーブルのソートと同様ですが、Host
カラムのみワイルドカードを含めることができるため、よりシンプルです。
サーバーはソート済みテーブルを使用して、サーバーが受け取るリクエストを検証します。SHUTDOWN
や RELOAD
などの管理権限が必要なリクエストでは、サーバーは user
テーブル行のみチェックします。これは、管理権限を指定するのはこのテーブルだけであるためです。リクエストされた操作がその行によって許可される場合、サーバーはアクセス権限を付与し、そうでない場合はアクセスを拒否します。たとえば、ユーザーが mysqladmin shutdown を実行したいが、user
テーブル行によって SHUTDOWN
権限がユーザーに付与されていない場合、サーバーは db
テーブルさえもチェックせずにアクセスを拒否します。(これには Shutdown_priv
カラムがないため、実行は不要です。)
データベース関連のリクエスト (INSERT
、UPDATE
など) の場合、サーバーは user
テーブル行を参照することによって、ユーザーのグローバル権限を最初にチェックします。リクエストされた操作が行で許可されている場合、アクセス権限が付与されます。user
テーブル内のグローバル権限が不十分な場合、サーバーは db
テーブルをチェックすることによってユーザーのデータベース固有の権限を調べます。
サーバーは、db
テーブルを参照し Host
、Db
、および User
カラムの一致がないかチェックします。Host
および User
カラムは、接続するユーザーのホスト名および MySQL ユーザー名に突き合わせされます。Db
カラムは、ユーザーがアクセスしようとしているデータベースに突き合わせされます。Host
および User
に該当する行がない場合、アクセスは拒否されます。
db
テーブルエントリによって付与されるデータベース固有の権限を判別したあと、サーバーは user
テーブルによって付与されるグローバル権限にそれらの権限を追加します。その結果、リクエストされた操作が許可される場合、アクセス権限が付与されます。そうでない場合、サーバーは続けて tables_priv
および columns_priv
テーブル内でユーザーのテーブル権限およびカラム権限をチェックし、これらをユーザーの権限に追加し、結果に基づいてアクセスを許可または拒否します。ストアドルーチン操作の場合、サーバーは tables_priv
および columns_priv
の代わりに procs_priv
テーブルを使用します。
ブール条件によって表現すると、ユーザーの権限を計算する方法についての前述の説明は、次のように要約できます。
global privileges
OR (database privileges AND host privileges)
OR table privileges
OR column privileges
OR routine privileges
リクエストされた操作に対して user
行のグローバル権限が最初に十分ではないことがわかっている場合に、サーバーがそれらの権限をあとでデータベース権限、テーブル権限、およびカラム権限と組み合わせることの理由が明確でないかもしれません。この理由は、1 つのリクエストが複数のタイプの権限を必要とすることがあるためです。たとえば、INSERT INTO ... SELECT
ステートメントを実行する場合、INSERT
および SELECT
権限が両方必要です。使用する権限が、user
テーブル行で 1 つの権限を付与し、db
テーブル行でもう 1 つの権限を付与するようになっている場合があります。この状況で、リクエストを実行するために必要な権限はありますが、サーバーはいずれのテーブルから来たものかを見分けることができず、両方のテーブルのエントリによって付与される権限を組み合わせる必要があります。