GNU/Linux >> Linux の 問題 >  >> Linux

レガシー アプリケーションの PAM 認証

PAM の標準情報 (パスワードなど) が渡される方法は、pam_set_item で pam ハンドルに設定された変数を使用することです (pam_set_item のマニュアル ページを参照してください)。

アプリケーションが後で使用する必要があるものは何でも pam_stack に設定できます。パスワードを pam_stack に入れたい場合は、pam_start() を呼び出した直後に、以下の疑似コードのように PAM_AUTHTOK 変数をスタックに設定することで、それを実行できるはずです:

pam_handle_t* handle = NULL;
pam_start("common-auth", username, NULL, &handle);
pam_set_item( handle, PAM_AUTHTOK, password);

これにより、パスワードを使用する任意のモジュールがスタック上でパスワードを使用できるようになりますが、通常は、サービスの pam_configuration で標準の use_first_pass または try_first_pass オプション (この場合は /etc) を設定して、モジュールにパスワードを使用するように指示する必要があります。 /pam.d/common-auth).

標準の pam_unix モジュールは try_first_pass をサポートしているため、システムの pam 構成に (pam_unix の行の最後に) 追加しても害はありません。

これを行った後、pam_authenticate() へのすべての呼び出し common-auth サービスから呼び出されるものは、パスワードを取得してそれを使用する必要があります。

use_first_pass と try_first_pass の違いに関する小さな注意:どちらもモジュール (この場合は pam_unix) に pam_stack でパスワードを試すように指示しますが、パスワード/AUTHTOK が利用できない場合の動作が異なります。欠落している場合、use_first_pass は失敗し、try_first_pass により、モジュールはパスワードの入力を求めることができます。


これが私がやったことです。 3 つのアスタリスクでマークされたコメントを参照してください。

#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <security/pam_appl.h>
#include <unistd.h>

// To build this:
// g++ test.cpp -lpam -o test

// if pam header files missing try:
// sudo apt install libpam0g-dev

struct pam_response *reply;

//function used to get user input
int function_conversation(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr)
{
  *resp = reply;
  return PAM_SUCCESS;
}

int main(int argc, char** argv)
{
  if(argc != 2) {
      fprintf(stderr, "Usage: check_user <username>\n");
      exit(1);
  }
  const char *username;
  username = argv[1];

  const struct pam_conv local_conversation = { function_conversation, NULL };
  pam_handle_t *local_auth_handle = NULL; // this gets set by pam_start

  int retval;

  // local_auth_handle gets set based on the service
  retval = pam_start("common-auth", username, &local_conversation, &local_auth_handle);

  if (retval != PAM_SUCCESS)
  {
    std::cout << "pam_start returned " << retval << std::endl;
    exit(retval);
  }

  reply = (struct pam_response *)malloc(sizeof(struct pam_response));

  // *** Get the password by any method, or maybe it was passed into this function.
  reply[0].resp = getpass("Password: ");
  reply[0].resp_retcode = 0;

  retval = pam_authenticate(local_auth_handle, 0);

  if (retval != PAM_SUCCESS)
  {
    if (retval == PAM_AUTH_ERR)
    {
      std::cout << "Authentication failure." << std::endl;
    }
    else
    {
      std::cout << "pam_authenticate returned " << retval << std::endl;
    }
    exit(retval);
  }

  std::cout << "Authenticated." << std::endl;

  retval = pam_end(local_auth_handle, retval);

  if (retval != PAM_SUCCESS)
  {
    std::cout << "pam_end returned " << retval << std::endl;
    exit(retval);
  }

  return retval;
}

Linux
  1. Flatpakアプリケーションのシークレット管理への3つのアプローチ

  2. Linuxでのキーベースの認証にssh-keygenと共有を使用する

  3. 追加の電子メール認証用にSPFを設定する方法

  1. Linux –カレンダーに使用するアプリケーションはどれですか?

  2. tomboy-ng –デスクトップ用の簡単なメモ取りアプリケーション

  3. sshd:特定のユーザーに対して PAM 認証を有効にする方法

  1. トラフィックの多いイベントに備える

  2. Linux アプリケーションの syscall アクセスを制限する

  3. chsh:PAM 認証に失敗しました