2

UNIXシステムでユーザーが属するすべてのグループを見つけようとしています.ImplementationはCで行う必要があります。これが私のコードです:

#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <pwd.h>
#include <grp.h>


static void error_fatal(char* msg) 
{ perror(msg); exit(EXIT_FAILURE); }

int main(int argc, char** argv) {

    struct group* grp;
    struct passwd* pwd;
    char *name;
    int i = 0;

    setpwent();

    while((pwd = getpwent()) != NULL){

        if(  ( name = (char*) malloc( (strlen(pwd->pw_name)+1)*sizeof(char))) == NULL  ) error_fatal("malloc");
        strcpy(name, pwd->pw_name);
        printf("%s:\n", name); 

        setgrent();
        while( (grp = getgrent()) != NULL ) {
            for( i=0; i < (sizeof(grp->gr_mem)/sizeof(grp->gr_mem[0])); i++ ){
                if( /*strlen(&grp->gr_mem[i][0]) == strlen(name) && */ !strcmp(grp->gr_mem[i], name) )
                     printf("%s\n", name);
}                           }

        endgrent(); 
        free(name);

}
    endpwent();

    return 0;
}

しかし、「root:」の出力後にセグメンテーション違反が発生します。問題は、/etc/group ファイルの 4 番目のフィールドにあるメンバーのリストにアクセスすることにあると確信しています (詳細については、man 5 group を参照してください)。

したがって、基本的に私の問題は、各グループが何人のメンバーを持っているかを調べることです。そのため、私のカウンター (プログラム内の i、最後の for ループ) には適切な上限があります。

4

2 に答える 2

1

あなたの問題はここにあります:

for( i=0; i < (sizeof(grp->gr_mem)/sizeof(grp->gr_mem[0])); i++ ){

struct groupと定義されている:

       struct group {
           char   *gr_name;        /* group name */
           char   *gr_passwd;      /* group password */
           gid_t   gr_gid;         /* group ID */
           char  **gr_mem;         /* NULL-terminated array of pointers
                                      to names of group members */
       };

あなたはgr_mem配列であると仮定していますが、そうではありません。配列の最初の要素を指すポインターです。したがってsizeof(grp->gr_mem)/sizeof(grp->gr_mem[0])、ポインターのサイズが得られます。システムではおそらく8です。gr_memそのため、ユーザーのグループが 8 つ未満の場合、配列ポイントの末尾を超えて読み取りを開始することになります。

が指す配列gr_memは NULL で終了するため、ターミネータを見つけると、ループがいつ終了するかがわかります。

for( i=0; grp->gr_mem[i]; i++ ){
于 2018-12-07T19:48:31.263 に答える