c - PAM 的不同访问级别

标签 c linux security authentication pam

目前我有一个图形应用程序,有两个级别的访问权限:运算符(operator)和管理员。登录和身份验证都是自制的,我想将应用程序切换为使用 PAM。我不确定正确的方法是什么。

如果我错了,请纠正我,但 PAM 似乎可以归结为"is"或“否”检查 - 是的,您可以访问此服务,否则,您不能。没有根据登录的用户提供不同级别的访问权限。不过,我需要能够区分谁是运算符(operator)、谁是管理员,并且如果可能的话,我希望能够严格通过 PAM 来做到这一点。

所以我的想法是,我会设置具有两种不同配置的两个服务/etc/pam.d/pamdemo 用于运算符(operator)和 /etc/pam.d/pamdemo-admin 用于管理员。然后,我的应用程序将首先尝试对 pamdemo-admin 进行身份验证,如果失败,则再对 pamdemo 进行身份验证。如果两者都失败,则访问被拒绝。 我是在正确的轨道上还是完全偏离轨道?

这是我编写的一些示例 C 代码作为概念证明。当我登录时,我不想两次提示用户输入凭据。我已经得到它,因此它会记住两个 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;
}

正如所写,此演示程序重复“密码:”提示。我不想让它问两次!

最佳答案

我相信一种正确的方法可能是:

  • 设置“pamdemo”服务来执行帐户、身份验证和 session 功能。
  • 将“pamdemo-admin”服务设置为执行帐户(可能还有 session )功能。没有身份验证。
  • 登录时,首先让他们通过“pamdemo”(以确保他们的真实身份) - 如果失败,请将他们踢出。
  • 然后,经过身份验证后,将它们交给“pamdemo-admin”。这只是检查他们是否被允许成为管理员 - 如果是,则此检查成功,如果不是,则不会。由于此检查不执行身份验证模块,因此不会再次提示他们输入密码。

关于c - PAM 的不同访问级别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1168552/

相关文章:

c - 如何调度进程

c - fgetc,检查 EOF

linux - ttyusb udev 按硬件端口命名

ios - 以编程方式检查是否在 iOS 7 上设置了密码锁

c - 返回对 C 中函数指针的调用

c - Fifo 与客户端/服务器

linux - xclip 在跟踪它时不会终止

linux - 使用 GetOpts 和强制参数验证命令行参数

security - Apple Pay token transactionId 是否全局唯一?

c++ - 如何以编程方式从 Firefox 获取证书?