GETGROUPLIST(3)

名前
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/ に書かれている。