0

学校のコンピューター室の準備作業として、UNIX でログイン プロセスをシミュレートする ac プログラムを作成するよう求められました。プログラムは端末からユーザー名とパスワードを読み取り、/etc/passwd に似ているはずのローカル ファイル内のハッシュ値と比較します。

これが私が持っているものです:

/*
 * Program mylogin.c
 *
 * This program prompts the user for a login name and password
 *
 */

#define _XOPEN_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pwd.h>
#include <sys/types.h>
#include <string.h>

/* define some error constants */
#define NOUSER -1

/* define max size of a username */
#define USERNAME_SIZE 32
#define PASSWORD_SIZE 32
#define HASH_SIZE 32
#define FAILED_LIMIT 5
#define AGE_LIMIT 10

int read_username(char *username)
{

    printf("login: ");
    fgets(username,USERNAME_SIZE,stdin);

    /* remove the CR included by getline() */
    username[strlen(username)-1]='\0';
    return(0);
}

int read_password(char *password)
{

    printf("password: ");
    fgets(password,PASSWORD_SIZE,stdin);
    //getpass(password);

    /* remove the CR included by getline() */
    password[strlen(password)-1]='\0';
    return(0);
}

int user_exists(const char *username)
{
    struct pwdb_passwd *pw_entry;

    pw_entry=getpwnam(username);
    return((pw_entry)!=NULL);
}

int main(int argc,char **argv)
{
    char username[USERNAME_SIZE];
    char* password;

    /* write "login:" and read user input */
    read_username(username);
    read_password(password);

    if (!user_exists(username))
    {
        printf("Unknown user or authentication\n");
        main(argc, argv);
    }
    struct pwdb_passwd *pw_entry = getpwnam(username);
    char* hashed_password = crypt(password,pw_entry->pw_passwd);
    if(strcmp(hashed_password,  pw_entry->pw_passwd)==0)
    {
        if((pw_entry->pw_failed)<FAILED_LIMIT)
        {
            printf("User authenticated successfully\n");
            pw_entry->pw_age++;
            pw_entry->pw_failed = 0;
            pwdb_update_user(pw_entry);
        }else{
            printf("User account locked\n");
            main(argc, argv);
        }
    }
    else
    {
        printf("Unknown user or authentication\n");
        pw_entry->pw_failed++;
        if(pw_entry->pw_failed>5){
            printf("Too many failed attempts. Username now locked\n");
        }
        pwdb_update_user(pw_entry);
        main(argc, argv);
    }
    return(0);
}

構造体 pwdb_passwd は、ファイル pwdb_lib.c および pwdb_lib.h で定義されており、既に書き込まれています。

プログラムをコンパイルすると、いくつかのエラーが発生します。たとえば、73 行目で、「エラー: 不完全な型へのポインターを逆参照しています」というメッセージが表示されます。

理由がわかりません。それは好きではないようですpw_entry->pw_passwd。さらに言えば、Windows で Code::Blocks (gcc を使用) を使用してコンパイルすると、Ubuntu で gcc を使用する場合とは異なるエラーが発生します。これはかなり奇妙だと思います。pwd.h をインポートし、Windows ではなく Linux にのみ存在することが原因である可能性があると思われます。これは正しいでしょうか?独自の pwd.h ファイルを作成して同じディレクトリに保存しようとしましたが、それでも機能しませんでした。ubuntu コンピューターに移行すると、pwd.h からエラーが発生しませんが、代わりに「不完全な型へのポインターを逆参照しています」というエラーが発生します。

コードの何が問題になっていますか?

また、user_exists 関数でのメモリ リークも疑われますが、プログラム全体に影響があるかどうかはわかりません。

4

2 に答える 2

1

は既に記述されていpwdb_lib.cますが、ソース ファイルに含める必要があります。

追加

#include "pwdb_lib.h"

ソースに追加し、コンパイル/リンクしていることを確認してくださいpwdb_lib.c

この#includeファイルを ing することで、ソース ファイルに実装を提供することなく、その中の定義について知らせることができます。最後に、プログラムをコンパイルするときpwdb_lib.c(または、オブジェクト ファイルをリンクするとき)、これらの定義を含むすべてのソースに、それらが実装されている場所を知らせます (したがって、それらを使用できるようにします)。 )。

于 2013-02-19T16:50:49.597 に答える
1

ヘッダーの名前が の場合、pwdb_lib.hなぜあなたのプログラムはそれを実行しない#includeのでしょうか? 別のヘッダー ( pwd.h) が含まれているようですが、どれですか?

表示されるエラーは、宣言が欠落している場合に予想されるものです。

于 2013-02-19T16:50:51.027 に答える