PAM 是一种在 MacOS 上验证用户身份的合适方法吗

Is PAM an appropriate method to authenticate a user on MacOS

我正在尝试使用 PAM 和以下代码在 MacOS 上对用户进行身份验证:

#include <security/pam_appl.h>

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

static int PamCallbackFn( int num_msg,
            const struct pam_message **msg,
            struct pam_response **resp,
            void *appdata_ptr )
{
    printf("PamCallbackFn num_msg=%d:\n", num_msg );
    for ( int idx = 0; idx < num_msg; ++ idx )
    {
        printf(
            "\tPrompt type %d for '%s'\n", 
            msg[idx]->msg_style,
            msg[idx]->msg );
    }

    assert( num_msg == 1 );
    struct pam_response *response = 
        (struct pam_response *)malloc( sizeof( struct pam_response ) );
    response->resp = strdup( "fhtest" );
    response->resp_retcode = 0;

    *resp = response;
    return PAM_SUCCESS;
}

int main( int argc, char **argv )
{
    struct pam_conv Callback;
    Callback.conv = PamCallbackFn;
    Callback.appdata_ptr = 0;

    printf("Calling pam_start()...\n");

    pam_handle_t *AuthHandle = 0;
    int Result = 
        pam_start(
            "test",     // Client program name
            "fhtest",   // User name
            &Callback,
            &AuthHandle );
    if ( Result != PAM_SUCCESS )
    {
        printf(
            "pam_start() returned %d (%s)\n",
            Result,
            pam_strerror( AuthHandle, Result ) );
        return EXIT_FAILURE;
    }

    printf("Calling pam_authenticate()...\n");
    Result = pam_authenticate( AuthHandle, PAM_SILENT );
    if ( Result != PAM_SUCCESS )
    {
        printf(
            "pam_authenticate() returned %d (%s)\n",
            Result,
            pam_strerror( AuthHandle, Result ) );
        return EXIT_FAILURE;
    }

    printf("Calling pam_acct_mgmt()...\n");
    Result = pam_acct_mgmt( AuthHandle, 0 );
    if ( Result != PAM_SUCCESS )
    {
        printf(
            "pam_acct_mgmt() returned %d (%s)\n",
            Result,
            pam_strerror( AuthHandle, Result ) );
        return EXIT_FAILURE;
    }

    printf("Success !\n");
    pam_end( AuthHandle, Result );
    return EXIT_SUCCESS;
}

MacOS 上的编译和运行命令是:

clang pamtest.c -lpam
sudo ./a.out

然而,当代码在 MacOS 上为 运行 时,输出为:

Calling pam_start()…
Calling pam_authenticate()…
pam_authenticate() returned 9 (authentication error)

pam 未尝试调用 PamCallbackFn() 来提供密码。

如果在 Ubuntu 上编译相同的代码并 运行,验证成功,我得到以下输出:

Calling pam_start()…
Calling pam_authenticate()…
PamCallbackFn num_msg=1
    Prompt type 1 for 'Password: '
Calling pam_acct_mgmt()…
Success !

用户帐户 fhtest 存在于 MacOSUbuntu 上。我可以使用此帐户手动登录两台计算机。

/etc/pam.d 中 "test" 没有特定的 pam 服务文件(pam_start 调用的第一个参数)。在这种情况下,pam 应该回退到使用 /etc/pam.conf。文件 /etc/pam.conf 存在于 Ubuntu 计算机上,但仅包含注释。文件 /etc/pam.conf 在 MacOS 计算机上不存在。在 MacOS 计算机上创建类似于 Ubuntu 计算机上的文件 /etc/pam/conf 并不能解决问题。

我正在寻找的是如何在 MacOS 上使用 UserNamePassword 对用户进行身份验证的工作示例。该解决方案应该可以从后台服务或守护进程使用。

PAM 是身份验证任务的接口,它本身不进行身份验证(例如,它可以将身份验证委托给远程 Kerberos 或 LDAP 服务器,或本地登录系统)。

配置必须在 /etc/pam.d/etc/pam.conf 中的系统级别完成。您应该验证您的配置是否正确。例如,由于您的服务名称是 "test",您可能需要一个文件 /etc/pam.d/test

或者您可以尝试在 pam_start() 调用中选择其他服务名称。例如 "login".