Provided by: manpages-ja-dev_0.5.0.0.20221215+dfsg-1_all bug

名前

       getgrouplist - ユーザーが所属するグループのリストを取得する

書式

       #include <grp.h>

       int getgrouplist(const char *user, gid_t group,
        gid_t *groups, int *ngroups);

   glibc 向けの機能検査マクロの要件 (feature_test_macros(7)  参照):

       getgrouplist():
           glibc 2.19 以降:
               _DEFAULT_SOURCE
           glibc 2.19 以前:
               _BSD_SOURCE

説明

       getgrouplist()  関数は、グループデータベース (group(5)  参照) を調べて、 user が所属するグ
       ループのリストを取得する。  見つかったグループのうち最大   *ngroups   個のグループが、配列
       groups に格納されて返される。

       引数 group がグループデータベースに user が所属するグループがなかった場合、 getgrouplist()
       が返すグループのリストに引数 group も追加される。 通常は、この引数にはユーザー user のパス
       ワードレコードに書かれているグループ ID を指定する。

       引数  ngroups  は、値渡しと結果の両方に使用される引数  (value-result argument) であり、 リ
       ターン時には、常に group も含めた user が所属するグループ数が格納される。 この値は  groups
       に格納されたグループ数より大きくなる可能性がある。

返り値

       user が所属しているグループ数が *ngroups 以下の場合、 *ngroups の値が返される。

       指定されたユーザーが *ngroups より多くのグループに所属している場合、 getgrouplist()  は -1
       を返す。  この場合、   *ngroups   で返される値を使って、バッファーのサイズを変更してから、
       getgrouplist() をもう一度呼び出すことができる。

バージョン

       この関数は glibc 2.2.4 から存在する。

属性

       この節で使用されている用語の説明については、 attributes(7) を参照。

       ┌─────────────────┬───────────────┬────────────────┐
       │インターフェース属性             │
       ├─────────────────┼───────────────┼────────────────┤
       │getgrouplist()   │ Thread safety │ MT-Safe locale │
       └─────────────────┴───────────────┴────────────────┘

準拠

       この関数は非標準である。ほとんどの BSD に存在する。

バグ

       バージョン  2.3.3 より前の glibc では、 この関数の実装にはバッファーオーバーフローのバグが
       あり、 user が所属するグループ数が *ngroups より多い場合であっても、 user が所属するグルー
       プの全リストを配列 groups に格納してしまう。

       以下のプログラムは、一つ目のコマンドライン引数で指定された名前のユーザー  が所属するグルー
       プのリストを表示する。 二番目のコマンドライン引数には、 getgrouplist()  に渡す ngroups  の
       値を指定する。 以下のシェルのセッションはこのプログラムの使用例を示したものである。

           $ ./a.out cecilia 0
           getgrouplist() returned -1; ngroups = 3
           $ ./a.out cecilia 3
           ngroups = 3
           16 (dialout)
           33 (video)
           100 (users)

   プログラムのソース

       #include <stdio.h>
       #include <stdlib.h>
       #include <grp.h>
       #include <pwd.h>

       int
       main(int argc, char *argv[])
       {
           int ngroups;
           struct passwd *pw;
           struct group *gr;

           if (argc != 3) {
               fprintf(stderr, "Usage: %s <user> <ngroups>\n", argv[0]);
               exit(EXIT_FAILURE);
           }

           ngroups = atoi(argv[2]);

           gid_t *groups = malloc(sizeof(*groups) * ngroups);
           if (groups == NULL) {
               perror("malloc");
               exit(EXIT_FAILURE);
           }

           /* Fetch passwd structure (contains first group ID for user) */

           pw = getpwnam(argv[1]);
           if (pw == NULL) {
               perror("getpwnam");
               exit(EXIT_SUCCESS);
           }

           /* Retrieve group list */

           if (getgrouplist(argv[1], pw->pw_gid, groups, &ngroups) == -1) {
               fprintf(stderr, "getgrouplist() returned -1; ngroups = %d\n",
                       ngroups);
               exit(EXIT_FAILURE);
           }

           /* Display list of retrieved groups, along with group names */

           fprintf(stderr, "ngroups = %d\n", ngroups);
           for (int j = 0; j < ngroups; j++) {
               printf("%d", groups[j]);
               gr = getgrgid(groups[j]);
               if (gr != NULL)
                   printf(" (%s)", gr->gr_name);
               printf("\n");
           }

           exit(EXIT_SUCCESS);
       }

関連項目

       getgroups(2), setgroups(2), getgrent(3), group_member(3), group(5), passwd(5)

この文書について

       この man ページは Linux man-pages プロジェクトのリリース 5.10 の一部である。プロジェクトの
       説明とバグ報告に関する情報は https://www.kernel.org/doc/man-pages/ に書かれている。