什么也不要说,先来一个程序吧。
/*
注意要和你的系统一致redhat是这样/etc/pam.d/check_user
auth required /lib/security/pam_unix_auth.so
account required /lib/security/pam_unix_acct.so
1.如果需要出现密码弹出框还需要在添加
/etc/security/console.apps/check_user
USER=root
PROGRAM=~/check_user #这个路径就是下面编译好后的路径,不能和3中作链接的路径一样
SESSION=true
2.再对/usr/bin/consolehelper作ln
sudo ln -s consolehelper check_user
3.这样运行/usr/bin/check_user就实际在调用consolehelper,再去读取
/etc/security/console.apps/check_user里PROGRAM设定的路径
4.编译时要这样:
gcc check.c -ldl -lpam -lpam_misc -o ~/check_user
*/
#include <security/pam_appl.h>
#include <security/pam_misc.h>
#include <stdio.h>
static struct pam_conv conv = {
misc_conv, //定义在pam_misc.h中, 方便你编程
NULL
};
int main(int argc, char *argv[])
{
pam_handle_t *pamh=NULL;
int retval;
const char *user="root"; //用户名设置为系统上的一个合法用户
if(argc == 2) {
user = argv[1];
}
if(argc > 2) {
fprintf(stderr, "Usage: check_user [username]\n");
exit(1);
}
retval = pam_start("check_user", user, &conv, &pamh);
/* 开始 */
if (retval == PAM_SUCCESS)
retval = pam_authenticate(pamh, 0);
/* 认证是不是该用户? 提示你输入一个密码 */
if (retval == PAM_SUCCESS)
retval = pam_acct_mgmt(pamh, 0);
/* 账号是否有效? */
if (retval == PAM_SUCCESS) {
fprintf(stdout, "Authenticated\n");
} else {
fprintf(stdout, "Not Authenticated\n");
}
if (pam_end(pamh,retval) != PAM_SUCCESS) {
/* 结束 */
pamh = NULL;
fprintf(stderr, "check_user: failed to release authenticator\n");
exit(1);
}
return ( retval == PAM_SUCCESS ? 0:1 ); /* indicate success */
}
#gcc check.c -ldl -lpam -lpam_misc -o check_user
编译得到这个check_user这个可执行程序之后,再在/etc/pam.d/目录下,添加一个文本文件,保存为check_user(要同源码 pam_start函数的第一个参数一样),往文件里写入如下内容:
auth required /lib/security/pam_unix_auth.so
account required /lib/security/pam_unix_acct.so
接下来便是验证这个程序了:
[root@ecy c]# ./check_user
Password:
Authenticated
ok,输入密码为源码中users对应的用户的密码。通过这个程序能略知PAM的工作方式。
从来没有意识到PAM在Linux运用如此之广,重要如此之大。我们知道,当我们登陆系统的时候,是要运行login程序的,在/etc/pam.d/目录下是有一个login文件的,查看下里面的内容:
[root@ecy pam.d]# cat login
#%PAM-1.0
auth [user_unknown=ignore success=ok ignore=ignore default=bad] pam_securetty.so
auth include system-auth
account required pam_nologin.so
account include system-auth
password include system-auth
# pam_selinux.so close should be the first session rule
session required pam_selinux.so close
session required pam_loginuid.so
session optional pam_console.so
# pam_selinux.so open should only be followed by sessions to be executed in the user context
session required pam_selinux.so open
session required pam_namespace.so
session optional pam_keyinit.so force revoke
session include system-auth
session optional pam_ck_connector.so
我开始意识到是不是我们的login程序也象上面那个check_user程序一样调用了大量PAM的API,于是我要验证一下:
[root@ecy pam.d]# strings /bin/login | grep pam
libpam.so.0
pam_close_session
pam_set_item
pam_authenticate
pam_strerror
pam_setcred
pam_start
pam_getenvlist
pam_acct_mgmt
pam_end
pam_chauthtok
pam_get_item
pam_open_session
libpam_misc.so.0
呵呵,确实是这样的。Linux中几乎所有的服务都用到了PAM,比如vsftpd。
[root@ecy pam.d]# strings /usr/sbin/vsftpd | grep pam
libpam.so.0
pam_close_session
pam_set_item
pam_authenticate
pam_setcred
pam_start
pam_acct_mgmt
pam_end
pam_open_session
tunable_pam_service_name
pam_service_name
dodgy nmsg in pam_conv_func
可见PAM对于Linux正常运行所具有的重要意义。
PAM的核心库放在/lib/目录下,可动态加载的库放在/lib/security目录下(Fedora 9)。在/etc/security/console.apps目录下有很多配置文件,很多sys-config-*的文件,事实上/usr/bin /sys-config-*都只是/usr/bin/consolehelper这个可执行文件的符号链接,不知道具体是如何运作的。如果将这个/etc /security/console.apps目录下相应的项删除掉,那么在终端再输入相应的命令就会提示错误了,这些配置文件应该是用于PAM管理终端 会话的。
这个巧妙而强大的认证方式又是Sun公司首创的~
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/xjtuse_mal/archive/2008/12/09/3484275.aspx