关于如何设计PAM的一些高级问题

时间:2013-06-15 20:22:27

标签: linux solaris pam

我正在为项目创建PAM模块。 PAM模块将使用一些库,该库将被某些命令行实用程序重用(而不是每次都重写所有内容)。在这个库中,我想让它解释根据远程主机的子网成员资格区分和/或记录的策略。接近,因为我可以告诉这个值可能来自验证应用程序,但我不知道。由于共享对象无法访问libpam中的pamh结构,因此我不能只执行pam_get_item(就像我可以从PAM模块本身那样),所以我不得不求助于其他方法。

我提出的最佳解决方案是让共享对象查找已连接的TTY,如果有,则转到utmp并找到与该TTY关联的登录进程,从那里提取IP地址。如果没有TTY,则假设它是网络用户的初始登录。然后,库会遍历套接字(当你执行ls -l /proc/<pid>/fd时,我已经定义为基本上任何带有“socket”字样的符号链接,并使用套接字inode编号与{{1进行交叉引用)并提取与该inode编号关联的远程IP地址。如果它没有在那里找到inode,那么它假定它是Unix域或tcp6(IPv6支持即将到来,并且在不久的将来不是非常重要)。如果它仍然无法找到它,假设某个守护进程已经调用了一个链接它的应用程序并将其解释为(如果它值得的话,最终可能会做一些事情,但是现在如果前两个没有,这只是一个很大的NOOP不归还任何东西。

它似乎有效但我对PAM应该如何工作有一些高级别的问题:

  1. 是否有一些管理PAM运营的官方标准?例如,它是否被某个POSIX标准覆盖?我知道有多个PAM实现(我已经发现了四个或五个),但我不知道现有的共性是法律上还是事实上的,或者我是如何配置系统的。

  2. 我从模块本身(通过/proc/net/tcp)开始ls -l /proc/<pid>/fd > /lsOutput之后:

  3.   

    [root @ hypervisor pam] #cat / lsOutput total 0

         

    lrwx ------。 1 root root 64 Jun 15 15:09 0 - &gt; / dev / null

         

    lrwx ------。 1 root root 64 Jun 15 15:09 1 - &gt; / dev / null

         

    lrwx ------。 1 root root 64 Jun 15 15:09 2 - &gt;的/ dev / null的

         

    LR-X ------。 1 root root 64 Jun 15 15:09 3 - &gt;插座:[426180]

         

    [root @ hypervisor pam]#

    在用户登录后发出手册system()

    ls

    基本上,似乎TTY和任何其他套接字都只在会话模块完成后打开(我的临时测试模块的会话处理是[root@hypervisor pam]# ls -l /proc/18261/fd total 0 lrwx------. 1 root root 64 Jun 15 15:15 0 -> /dev/null lrwx------. 1 root root 64 Jun 15 15:15 1 -> /dev/null lrwx------. 1 root root 64 Jun 15 15:15 11 -> /dev/ptmx lrwx------. 1 root root 64 Jun 15 15:15 12 -> /dev/ptmx lrwx------. 1 root root 64 Jun 15 15:15 13 -> socket:[426780] lrwx------. 1 root root 64 Jun 15 15:15 14 -> socket:[426829] lrwx------. 1 root root 64 Jun 15 15:15 2 -> /dev/null lrwx------. 1 root root 64 Jun 15 15:15 3 -> socket:[426180] lrwx------. 1 root root 64 Jun 15 15:15 4 -> socket:[426322] lr-x------. 1 root root 64 Jun 15 15:15 5 -> pipe:[426336] l-wx------. 1 root root 64 Jun 15 15:15 6 -> pipe:[426336] lrwx------. 1 root root 64 Jun 15 15:15 7 -> socket:[426348] lrwx------. 1 root root 64 Jun 15 15:15 8 -> socket:[426349] lrwx------. 1 root root 64 Jun 15 15:15 9 -> /dev/ptmx [root@hypervisor pam]# 服务的堆栈中的最后一个)。我一直无法得到它(或者甚至想到连接客户端不会成为描述符3的TCP套接字的时候)。

    这是因为我缺乏想象力还是一定如此?我倾向于后者,因为看起来与客户沟通将是做其他任何有用的事情的先决条件。我不确定,所以我觉得我应该问别人。描述符3总是作为身份验证客户端(我的.so只假设它是编号最小的TCP套接字,并且只有在没有TTY的情况下,但似乎sshd应始终是连接客户端的描述符) 。将第一个TCP描述符拉为建立远程客户端身份的“确定性”方式?或者是没有规定的方式应该发挥作用,这是我的系统配置或SSH如何选择与PAM接口?

    1. 3是设置rhost值还是来自其他地方?我已尝试sshd - 浏览SSH和libpam的源代码,但没有骰子。我可以看到libpam在调用pam_set_item时处理主机值的设置,但实际上没有调用pam_set_item来将其设置为此特定主机。
    2. 任何数量的帮助都会受到赞赏,我已经用Google搜索了,但是我开始在指尖上刮下碎片的底部。

      我有兴趣了解这一点的主要原因是,我不仅会以“正确”的答案结束,而且大部分时间以后我都不会有任何意外。我们可以使用一些Solaris平台,但我的主要动机是假设基于实际上将保持不变的事物。

      我也意识到我可以让客户端程序/模块将主机信息提供给库,但这可能会导致代码重写两到三次(因为CLI工具从utmp和PAM模块准备会话信息)来自pam_get_item)并且可能使项目看起来比实际需要的更复杂。

1 个答案:

答案 0 :(得分:0)

回答你的一些问题:

“是否有一些管理PAM操作的官方标准?”

显然,是的。维基百科在Pluggable_Authentication_Module上的条目说“PAM被标准化为X / Open UNIX标准化过程的一部分,导致X / Open单点登录(XSSO)标准。”我从未发现这与我与它的交易特别相关。

“这只是因为我缺乏想象力还是必然如此?”

&lt; magicEightBall&gt;“专注并再次询问”&lt; / magicEightBall&gt; (提到“这个”的含糊不清 - 也许你可以澄清一下?

“描述符3是否始终是验证客户端?”

这是应用程序的行为,而不是PAM。

拉第一个TCP描述符是否是建立远程客户端身份的“确定性”方式?

也是应用程序的行为。

“sshd是设置rhost值还是来自其他地方?”

设置rhost值的是sshd。在openssh的文件auth-pam.c中,函数sshpam_init(),你会发现:

sshpam_err = pam_set_item(sshpam_handle, PAM_RHOST, pam_rhost);

一些一般性说明:

  • 而不是关闭TTY - 正如你后来发现的那样 - 你可以通过getppid()和/ proc来处理流程沿袭。
  • 不信任PAM模块中的system() - 它使用用户的环境,可能不是您期望的环境。请改用fork()/ execlp()。