シナリオは次のとおりです。ルートとして実行できないコマンドラインプログラムがあります。要件の一部は、特定のフォルダ/ファイルに対する書き込み権限を持つ他のユーザーに警告することです。
例えば
- root ではなくユーザー A として実行しています。
- 「ユーザーBにフォルダFへの書き込み権限がありますか?」という質問に対する答えを得たいと思います。
だから私の質問は
- rootでも実行できますか?それではどうでしょうか?
- root以外のユーザーでこれを行う方法はありますか?
答え1
一般に、ユーザーBがディレクトリDに書き込むことができるかどうかを知る唯一の方法は、ユーザーBがディレクトリDに書き込もうとすることです。
したがって、rootとしてsu
そのユーザーとして試すことができます。これは100%正確ではないかもしれませんが、ユーザーがログインしてパスワードを入力すると状況が変わる可能性があります(たとえば、pamモジュールはユーザーのパスワードに基づいて暗号化キーを設定できます)。
ほぼルートほど正確なので、システムコールや同様のコマンドをsu
ユーザーにaccess(2)
使用できます。test -w
マン/usr/bin/test
ページで警告されているように、NFSv2では実際スキャンはサーバー上で実行されますが、access
システムコールのテストはローカルで行われるため、間違っている可能性があります。同様に、FUSEファイルシステムも同じことができます。
(access(2)
マンページには、現在実行中の作業に重要な競合条件も記載されています。Dに対するBの権限は、確認する時間とBが実際にDに書き込もうとする時間の間で変更されることがあります。)
それに加えて、次のことをどれだけ正確に受け入れるかを決定する必要があります。
- ディレクトリ数を計算し、ユーザーとグループを確認できます(他のいくつかの回答に表示されます)。
- ディレクトリでACLを確認することもできます。
しかし、そうしても、次のような状況が問題を引き起こす可能性があります。
- NFSや他のさまざまなネットワークファイルシステムを介して仕える人アクセスを許可するかどうかを決定します。必要な方法で決定を下すことができます。たとえば、さまざまなPumpkin NFSエクスポートオプションを考えてみましょう。
- 権限の確認は実際にはファイルシステムによって行われます。 Unix以外のファイルシステムは予期しない答えを提供する可能性があります(UnixユーザーはどのようにNTFS SIDにマップしますか?)。すべての賭けはFUSEファイルシステムにあります。
答え2
「ユーザーBにフォルダFへの書き込み権限がありますか?」
ユーザーAがこれを決定できるかどうかは、フォルダFへのAのアクセス権によって異なります。たとえば、Fがあり/home/B/foo/bar
、Aが読み取れない場合、/home/B/foo
AはFにどの権限が設定されているかは言うまでもなく、Fが存在するかどうかを確認することもできません。
A が F に対する読み取りアクセス権を持っているので、1 がstat()
Fに対する権限を取得すると仮定すると、次のステップは B が所有者かグループに属しているかを確認することです。後者の場合getgrent()
(基本C - マニュアルページがあります。パラメータを使用せずに一度に1つの項目を繰り返す)を使用して、グループのユーザー/etc/group
リストを取得できますstruct group
。
struct group {
char *gr_name; /* group name */
char *gr_passwd; /* group password */
gid_t gr_gid; /* group ID */
char **gr_mem; /* group members */
};
最後のフィールドgr_mem
は、ユーザー名のリストを含む文字列の配列です(リストはNULL
ポインタで終わります)。ファイルモードと組み合わせると、特定のユーザーに書き込みアクセス権があるかどうかを知らせるのに十分です。
getgrent()
を使用してIDとメンバーを含むグループのリストを印刷する例:
#include <stdio.h>
#include <sys/types.h>
#include <grp.h>
// std=c99
int main (void) {
struct group *ent = getgrent();
while (ent) {
printf (
"%s GID %d\n",
ent->gr_name,
ent->gr_gid
);
int i = 0;
char *p = ent->gr_mem[i];
while (p) {
printf("\t%s\n", p);
p = ent->gr_mem[++i];
}
ent = getgrent();
}
return 0;
}
アクセス/etc/group
(および使用getgrent()
)には権限は必要ありません。
1 あなたはどの言語を使用しているか言及していませんが、「stat」はかなり不可論的であると予想しています。 getgrent()
ほとんども移植する必要がありますが、移植する方法は言語によって異なります。
答え3
最初の質問に答えるには(rootとして実行):
はい - >su - userB -c '<command as userB to touch file in folderF>'
2番目の質問に答えるには:
可能 - >非ユーザーがuserBと同じグループにあり、フォルダFのファイルをタッチしようとした場合にのみ可能
答え4
私が理解したことが正しい場合は、特定のフォルダに対するユーザー権限を確認する必要があります。
したがって、デフォルトでは、まずユーザーに対してgroupsコマンドを実行します。
groups userB
上記のコマンドは、自分が属するすべてのグループを一覧表示しますuserB
。以来、
コマンドを使用してstat
8進数権限を検索するフォルダ次のように。
stat -c "%a %n" /some-folder
上記のコマンドは、その特定の項目に対する8進数の権限を返します。フォルダ/文書。
たとえば、上記のコマンドが返された場合775話、これはuser
完全にgroup
アクセスできることをrwx
意味します。フォルダ others
r-x
アクセス可能フォルダ。
グループ決定ユーザーAgroups userA
両方の場合、コマンドを使用するだけでなく、ユーザーAそしてユーザーB同じグループに属することはユーザーB持つ書くファイル権限。