現在、オペレータと管理者の 2 つのレベルのアクセスを持つグラフィカル アプリケーションがあります。ログインと認証はすべて自作であり、代わりに PAM を使用するようにアプリケーションを切り替えたいと考えています。それを行う正しい方法が何であるかはわかりません。
私が間違っている場合は訂正してください。ただし、PAM は「はい」または「いいえ」のチェックに要約されるようです。つまり、このサービスにアクセスできるか、できないかです。どのユーザーがログインしているかに基づいて、さまざまなレベルのアクセス権を持つための規定はありません。ただし、誰がオペレーターで誰が管理者であるかを判別できるようにする必要があり、可能であれば PAM を介して厳密に実行できるようにしたいと考えています。
したがって、オペレーター用と管理者用の 2 つの異なる構成を持つ 2 つのサービスをセットアップすると思います。次に、私のアプリケーションは最初に認証を試み、それが失敗した場合は. 両方が失敗した場合、アクセスは拒否されます。私は正しい軌道に乗っていますか、それとも完全に脱線していますか?/etc/pam.d/pamdemo
/etc/pam.d/pamdemo-admin
pamdemo-admin
pamdemo
概念実証として作成した C コードのサンプルを次に示します。ログインを行うときに、ユーザーに資格情報を 2 回要求したくありません。2回の呼び出しでユーザー名を覚えているので、アプリケーションレベルからpam_start()
アクセスしてパスワードに対して同じキャッシュを行うことはできません。pam_get_item(PAM_AUTHTOK)
そして、そうしようとしていたときに、これを行うにはまったく別の方法があるかもしれないことに気づきました. ユーザー名/パスワード、Kerberos チケット、指紋など、認証方法に関係なく、このアプリケーションが機能することを望みます。
pam_handle_t *try_login(const char *service, int *retval)
{
static char * username = NULL;
struct pam_conv pam_conversation = { conv, NULL };
pam_handle_t * pamh;
*retval = pam_start(service, username, &pam_conversation, &pamh);
if (*retval == PAM_SUCCESS) *retval = pam_authenticate(pamh, 0);
if (*retval == PAM_SUCCESS) *retval = pam_acct_mgmt (pamh, 0);
if (*retval == PAM_SUCCESS) *retval = pam_open_session(pamh, 0);
if (username == NULL) {
if (pam_get_item(pamh, PAM_USER, (const void **) &username) == PAM_SUCCESS) {
username = strdup(username);
}
}
if (*retval != PAM_SUCCESS) {
fprintf(stderr, "%s: %s\n", service, pam_strerror(pamh, *retval));
pam_end(pamh, *retval);
pamh = NULL;
}
return pamh;
}
int main(void)
{
pam_handle_t *pamh = NULL;
int retval;
const char *service, *username;
if (!pamh) pamh = try_login("pamdemo-admin", &retval);
if (!pamh) pamh = try_login("pamdemo", &retval);
if (!pamh) {
fprintf(stderr, "Access denied.\n");
return 1;
}
pam_get_item(pamh, PAM_SERVICE, (const void **) &service);
pam_get_item(pamh, PAM_USER, (const void **) &username);
printf("Logged into %s as %s.\n", service, username);
pam_close_session(pamh, 0);
pam_end (pamh, retval);
return 0;
}
書かれているように、このデモ プログラムは "password:" プロンプトを繰り返します。二度も聞かれたくない!