我想用pam对我的c网络应用程序的用户进行身份验证,我在堆栈的底部找到了一个a nice PAM example。问题是,在我的开发机器中,我有一个指纹读取器,pam将使用它,如/etc/pam.d/common-auth

#%PAM-1.0
#
# This file is autogenerated by pam-config. All changes
# will be overwritten.
#
# Authentication-related modules common to all services
#
# This file is included from other service-specific PAM config files,
# and should contain a list of the authentication modules that define
# the central authentication scheme for use on the system
# (e.g., /etc/shadow, LDAP, Kerberos, etc.). The default is to use the
# traditional Unix authentication mechanisms.
#
auth    required    pam_env.so
auth    sufficient  pam_fprint.so
auth    optional    pam_gnome_keyring.so
auth    required    pam_unix2.so

pam_fprint.so是指纹读取器插件。当您正常登录时,扫描可能会失败,并提示您输入密码。但是,sshd守护进程根本不启动指纹,我想了解它是如何跳过指纹的,因为例如/etc/pam.d/sshd引用公共身份验证模块,所以它必须拉取指纹。
#%PAM-1.0
auth     requisite  pam_nologin.so
auth     include        common-auth
account  requisite      pam_nologin.so
account  include        common-account
password include        common-password
session  required   pam_loginuid.so
session  include        common-session
session  optional       pam_lastlog.so   silent noupdate showfailed

我试图从C程序中引用“sshd”方案,但它仍然启动指纹读取器。我想以某种方式跳过C中的指纹读取器,并保留我的指纹读取器默认配置。
    #include <stdlib.h>
    #include <iostream>
    #include <fstream>
    #include <security/pam_appl.h>
    #include <unistd.h>

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

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;
}

最佳答案

我怀疑sshd是否真的跳过了这个模块。相反,我怀疑指纹读取器身份验证模块(明智地)正在检查身份验证用户是出现在本地系统上,还是正在通过网络(它可以从pam数据(如rhost)来进行验证,如果这是网络身份验证,它只是静默地不做任何事情。您可以尝试查看源代码,看看它是否有这样的测试,或者尝试通过PAM_RHOST设置pam_set_item,看看这是否会改变行为。
为了回答您的实际问题,除了一个模块之外,我不相信有任何方法可以告诉pam运行特定的pam组。预期的方法是在/etc/pam.d中创建一个新的配置文件,该文件与传递给pam_start的应用程序名匹配,该文件不包含common-auth,而只包含要运行的模块。

10-08 07:35
查看更多