JavaScript is required to for searching.
ナビゲーションリンクをスキップ
印刷ビューの終了
Oracle Solaris 11 セキュリティーサービス開発ガイド     Oracle Solaris 11.1 Information Library (日本語)
このドキュメントの評価
search filter icon
search icon

ドキュメントの情報

はじめに

1.  Oracle Solaris の開発者向けセキュリティー機能 (概要)

2.  特権付きアプリケーションの開発

3.  PAM アプリケーションおよび PAM サービスの記述

PAM フレームワークの概要

PAM サービスモジュール

このリリースでの PAM への変更

PAM ライブラリ

PAM 認証プロセス

PAM コンシューマの要件

PAM 構成

/etc/pam.d を介した PAM の構成

PAM サービスを使用するアプリケーションの記述

単純な PAM コンシューマ例

その他の有用な PAM 関数

対話関数の記述

PAM サービスを提供するモジュールの記述

PAM サービスプロバイダの要件

PAM プロバイダサービスモジュールの例

4.  GSS-API を使用するアプリケーションの記述

5.  GSS-API クライアント例

6.  GSS-API サーバー例

7.  SASL を使用するアプリケーションの記述

8.  Oracle Solaris 暗号化フレームワークの紹介

9.  ユーザーレベルの暗号化アプリケーションの記述

10.  Oracle Solaris 鍵管理フレームワークの紹介

A.  開発者のためのセキュアコーディングガイドライン

B.  C ベース の GSS-API プログラム例

C.  GSS-API リファレンス

D.  OID の指定

E.  SASL ソースコード例

F.  SASL リファレンス

用語集

索引

ドキュメントの品質向上のためのご意見をください
簡潔すぎた
読みづらかった、または難し過ぎた
重要な情報が欠けていた
内容が間違っていた
翻訳版が必要
その他
Your rating has been updated
貴重なご意見を有り難うございました!

あなたの貴重なご意見はより良いドキュメント作成の手助けとなります 内容の品質向上と追加コメントのためのアンケートに参加されますか?

PAM サービスを使用するアプリケーションの記述

このセクションでは、いくつかの PAM 関数を使用するアプリケーション例を示します。

単純な PAM コンシューマ例

次の PAM コンシューマアプリケーションは、例示目的で提供されています。この例は、端末へのアクセスを試みるユーザーを検証する基本的な端末ロックアプリケーションです。

この例では、次の手順を実行します。

  1. PAM セッションを初期化します。

    PAM セッションは、pam_start(3PAM) 関数の呼び出しによって初期化されます。PAM コンシューマアプリケーションは、ほかの PAM 関数を呼び出す前に PAM セッションを最初に確立する必要があります。

    pam_start(3PAM) 関数は、次の引数を使用します。

    • plock – サービス名、つまり、アプリケーションの名前。サービス名は、PAM フレームワークで構成ファイル /etc/pam.conf 内または /etc/pam.d 内のどの規則が適切かを決定するために使用されます。通常、サービス名はロギングとエラーレポートに使用されます。

    • pw->pw_name – ユーザー名は、PAM フレームワークの対象となるユーザーの名前です。

    • &conv – 対話関数 conv は、PAM がユーザーまたはアプリケーションと通信するための汎用手段を提供しま す。PAM モジュールは通信の実施方法を認識する方法を持っていないため、対話関数が必要です。通信は、GUI、コマンド行、スマートカードリーダー、またはその他のデバイスを使用して行うことができます。詳細は、「対話関数の記述」を参照してください。

    • &pamh – PAM ハンドル pamh は、PAM フレームワークで現在の処理に関する情報を格納する際に使用される不透明なハンドルです。このハンドルは、pam_start() の呼び出しが成功することによって返されます。


    注 - PAM インタフェースを呼び出すアプリケーションは、認証、パスワードの変更、プロセス資格操作、監査状態の初期化など、すべての必要な処理を実行するための十分な特権を持っている必要があります。この例では、ローカルユーザーのパスワードを検証するために、アプリケーションは /etc/shadow を読み取り可能でなければなりません。


  2. ユーザーを認証します。

    アプリケーションは、pam_authenticate(3PAM) を呼び出して現在のユーザーを認証します。一般に、ユーザーは認証サービスの種類に応じて、パスワードまたはその他の認証トークンを入力する必要があります。

    PAM フレームワークは、/etc/pam.conf 内の、または Oracle Solaris 11.1 OS の場合は /etc/pam.d/plock 内の、認証のサービスモジュールタイプ auth に対応するサービス名 plock に構成されているモジュールを起動します。plock サービスの auth エントリが /etc/pam.conf または /etc/pam.d/plock に存在しない場合は、other サービスの auth エントリが /etc/pam.conf で検索され、最後に /etc/pam.d/other ファイルで検索されます。

  3. アカウントの有効性を確認します。

    例では、pam_acct_mgmt(3PAM) 関数を使用して、認証ユーザーのアカウントの有効性を確認します。この例では、pam_acct_mgmt() がパスワードの有効期限を確認します。

    pam_acct_mgmt() 関数は、PAM_DISALLOW_NULL_AUTHTOK フラグも使用します。pam_acct_mgmt() が PAM_NEW_AUTHTOK_REQD を返す場合は、認証ユーザーにパスワードの変更を許可するために、pam_chauthtok(3PAM) が呼び出されます。

  4. パスワードの有効期限が切れていることがシステムによって検出された場合は、ユーザーにパスワードの変更を強制します。

    例では、「成功」が返されるまでループを使用して pam_chauthtok() を呼び出します。ユーザーが認証情報 (通常はパスワード) の変更に成功した場合、pam_chauthtok() 関数は「成功」を返します。この例では、「成功」が返されるまでループが継続します。通常はアプリケーションで、終了するまでの最大試行回数を設定します。

  5. pam_setcred(3PAM) を呼び出します。

    pam_setcred(3PAM) 関数は、ユーザー資格の確立、変更、削除を行う際に使用されます。pam_setcred() は通常、ユーザー認証の完了時に呼び出されます。この呼び出しは、アカウントの検証完了後、セッションのオープン前に行われます。新しいユーザーセッションを確立する場合は、pam_setcred() 関数で PAM_ESTABLISH_CRED フラグを使用します。lockscreen の場合のように、セッションが既存セッションの更新版である場合、pam_setcred() を PAM_REFRESH_CRED フラグとともに呼び出すべきです。su を使用したり特定の役割を引き受けたりする場合のように、セッションが資格を変更する場合、pam_setcred() を PAM_REINITIALIZE_CRED フラグとともに呼び出すべきです。

  6. PAM セッションをクローズします。

    PAM セッションは、pam_end(3PAM) 関数の呼び出しによってクローズします。また、pam_end() は、すべての PAM リソースを解放します。

この PAM コンシューマアプリケーション例のソースコードを、次に示します。


注 - このソースコード例は、Oracle ダウンロードセンターからダウンロードすることも可能です。http://www.oracle.com/technetwork/indexes/downloads/sdlc-decommission-333274.html を参照してください。


例 3-1 PAM コンシューマアプリケーションの例

/*
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. */

#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <strings.h>
#include <signal.h>
#include <pwd.h>
#include <errno.h>
#include <security/pam_appl.h>

extern int pam_tty_conv(int num_msg, struct pam_message **msg,
         struct pam_response **response, void *appdata_ptr);

/* Disable keyboard interrupts (Ctrl-C, Ctrl-Z, Ctrl-\) */
static void
disable_kbd_signals(void)
{
    (void) signal(SIGINT, SIG_IGN);
    (void) signal(SIGTSTP, SIG_IGN);
    (void) signal(SIGQUIT, SIG_IGN);
}

/* Terminate current user session, i.e., logout */
static void
logout()
{
    pid_t pgroup = getpgrp();

    (void) signal(SIGTERM, SIG_IGN);
    (void) fprintf(stderr, "Sorry, your session can't be restored.\n");
    (void) fprintf(stderr, "Press return to terminate this session.\n");
    (void) getchar();
    (void) kill(-pgroup, SIGTERM);
    (void) sleep(2);
    (void) kill(-pgroup, SIGKILL);
    exit(-1);
}

int
/*ARGSUSED*/
main(int argc, char *argv)
{
    struct pam_conv conv = { pam_tty_conv, NULL };
    pam_handle_t *pamh;
    struct passwd *pw;
    int err;

    disable_kbd_signals();
    if ((pw = getpwuid(getuid())) == NULL) {
        (void) fprintf(stderr, "plock: Can't get username: %s\n",
            strerror(errno));
        exit(1);
    }
    
    /* Initialize PAM framework */
    err = pam_start("plock", pw->pw_name, &conv, &pamh);
    if (err != PAM_SUCCESS) {
        (void) fprintf(stderr, "plock: pam_start failed: %s\n",
            pam_strerror(pamh, err));
        exit(1);
    }

    /* Authenticate user in order to unlock screen */
    do {
        (void) fprintf(stderr, "Terminal locked for %s. ", pw->pw_name);
        err = pam_authenticate(pamh, 0);
        if (err == PAM_USER_UNKNOWN) {
            logout();
        } else if (err != PAM_SUCCESS) {
            (void) fprintf(stderr, "Invalid password.\n");
        }
    } while (err != PAM_SUCCESS);

    /* Make sure account and password are still valid */
    switch (err = pam_acct_mgmt(pamh, 0)) {
    case PAM_SUCCESS:
        break;
    case PAM_USER_UNKNOWN:
    case PAM_ACCT_EXPIRED:
        /* User not allowed in anymore */
        logout();
        break;
    case PAM_NEW_AUTHTOK_REQD:
        /* The user's password has expired. Get a new one */
        do {
            err = pam_chauthtok(pamh, 0);
        } while (err == PAM_AUTHTOK_ERR);
        if (err != PAM_SUCCESS)
            logout();
        break;
    default:
        logout();
    }

if (pam_setcred(pamh, PAM_REFRESH_CRED) != PAM_SUCCESS){
    logout();
}

    (void) pam_end(pamh, 0);
    return(0);
    /*NOTREACHED*/
}

その他の有用な PAM 関数

前記の単純なアプリケーション 例 3-1 では、主要 PAM 関数のうちほんの数種類しか使用されていません。このセクションでは、その他の有用な PAM 関数をいくつか紹介します。

pam_open_session(3PAM) 関数は、ユーザー認証が成功したあと、新しいセッションをオープンする際に呼び出されます。

pam_getenvlist(3PAM) 関数は、新しい環境を確立する際に呼び出されます。pam_getenvlist() は、既存環境にマージすべき新しい環境を返します。

pam_eval(3PAM) 関数は、呼び出し元によって指定されたファイルに格納されている PAM 構成を読み込み、評価します。この関数は pam_user_policy(5) PAM モジュールによって呼び出されます。