LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 608|回复: 2

关于PAM的一个验证过程,请了解PAM的进来。

[复制链接]
发表于 2005-9-8 19:07:25 | 显示全部楼层 |阅读模式
我要用PAM去实现一个用户验证的过程。我看了很多文章和例子但还是有很多不明白的地方,下面是我摘抄的一个例子,但是编译不过去,缺好多代码,而且有很多地方我看不懂,请哪位高人帮我解释一下,其中不懂的地方我用编号和问号表示出来了。在此先行谢过。


#include <security/pam_appl.h>
#include <security/pam_misc.h>

#include <sys/types.h>
#include <unistd.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>

/* 回调函数 */
static int login_conv(int num_msg, struct pam_message **msg, struct pam_response **response, void *appdata_ptr);
struct pam_conv pam_conv = {login_conv, NULL};
pam_handle_t *pamh;  // 进行认证的PAM句柄

/* 出错则清理现场并退出 */
static void login_exit(int exit_code)
{
   if (pamh)
       pam_end(pamh, PAM_ABORT);
   _exit(exit_code);
}

int main(int argc, char *argv[], char **renvp)
{
passwd *pwd;
   /* 初始化,并提供一个回调函数 */
   if ((pam_start("login", user, &pam_conv, &pamh)) != PAM_SUCCESS)
       login_exit(1);

   /* 设置一些参数 */
   pam_set_item(pamh, PAM_TTY, ttyn); //1、ttyn 是在哪里定义的?PAM_TTY是什么意思?
   pam_set_item(pamh, PAM_RHOST, remote_host);//2、remote_host在哪里定义的?PAM_RHOST是什么意思?

   while (!authenticated && retry < MAX_RETRIES)//3、authenticated和retry在哪里定义?这里是什么意思?
   {
       status = pam_authenticate(pamh, 0);        /* 密码认证管理,检查用户输入的密码是否正确 */
       authenticated = (status == PAM_SUCCESS);   //4、没看到有密码输入,如果检查,此处是否是交互式的
          // 如果是,能否在开始就将密码传入?
   }

   if (status != PAM_SUCCESS)
   {
       fprintf(stderr,"error: %s\n", pam_strerror(pamh, status)); /* 显示错误原因 */
       login_exit(1);
   }

   /*  通过了密码认证之后再调用帐户管理API,检查用户帐号是否已经过期 */
   if ((status = pam_acct_mgmt(pamh, 0)) != PAM_SUCCESS)
   {
       if (status == PAM_AUTHTOK_EXPIRED)
       {
           status = pam_chauthtok(pamh, 0);  /* 过期则要求用户更改密码 */
           if (status != PAM_SUCCESS)
               login_exit(1);
       }
   }

   /* 通过帐户管理检查之后则打开会话 */
   if (status = pam_open_session(pamh, 0) != PAM_SUCCESS)
       login_exit(status);

pwd = getpwnam(user);
   /* 设置用户组 */ //5、此处设置用户组有什么用?
   setgid(pwd->pw_gid);

   /*
   * Initialize the supplementary group access list before
   * pam_setcred because PAM modules might add groups
   * during the pam_setcred call
   */
   initgroups(user, pwd->pw_gid);

   status = pam_setcred(pamh, PAM_ESTABLISH_CRED);
   if (status != PAM_SUCCESS)
       login_exit(status);

   /* 设置真实的用户ID(或者有效的用户ID)*/
   setuid(pwd->pw_uid);

   pam_end(pamh, PAM_SUCCESS);  /* PAM事务的结束 */


   /*
   此处可用来实现与login有关的其它内容 //6、这里的其它内容指的是什么?
   */
}

/* 这个回调函数被PAM认证模块调用以便显示错误信息或者或者用来取得用户输入,采用图形界面的服务程序则应使用图形界面来取得 用户输入或显示提示信息*/
int login_conv(int num_msg, struct pam_message **msg, struct pam_response **response, void *appdata_ptr)
{
   while (num_msg--)
   {
       switch (m->msg_style)
       {
           case PAM_PROMPT_ECHO_OFF:
               r->resp = strdup(getpass(m->msg));
               break;
           case PAM_PROMPT_ECHO_ON:
               (void) fputs(m->msg, stdout);
               r->resp = malloc(PAM_MAX_RESP_SIZE);
               fgets(r->resp, PAM_MAX_RESP_SIZE, stdin);
               /* add code here to remove \n from fputs */
               break;
           case PAM_ERROR_MSG:
               (void) fputs(m->msg, stderr);
               break;
           case PAM_TEXT_INFO:
               (void) fputs(m->msg, stdout);
               break;
           default:
               log_error();
               break;
       }
   }
   return (PAM_SUCCESS);
}
发表于 2005-9-9 14:21:43 | 显示全部楼层
Some papers here:http://www.sun.com/software/solaris/pam/
Hope it will help you.
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-9-9 17:52:09 | 显示全部楼层
现在我可以利用PAM对login服务的用户进行验证了,但是对于其它的服务的验证似乎与login是一样的过程。当我用pam_start(“samba”, user, &pam_conv, &pamh);验证samba的用户时似乎还是用的login的验证过程。比如我在验证samba用户A时,A用户是系统的合法用户但不是samba的合法用户,可是验证结果也是成功。对于vsftpd也有类似的情况,这是为什么?我本来打算用一个程序去既能验证系统的用户又能验证samba、ftp等服务的用户,但我是想让这些服务都用相同的用户名和密码,可是我现在竟然连非法用户也能验证通过,这是为什么?

现在的代码如下:

#include <security/pam_appl.h>
#include <security/pam_misc.h>
#include <sys/types.h>
#include <unistd.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>

/* 回调函数 */
static int login_conv(int num_msg, const struct pam_message **msg, struct pam_response **response, void *appdata_ptr);
pam_handle_t *pamh; // 进行认证的PAM句柄

/* 出错则清理现场并退出 */
static void login_exit(int exit_code)
{
if (pamh)
pam_end(pamh, PAM_ABORT);
_exit(exit_code);
}

int main(int argc, char *argv[], char **renvp)
{
passwd *pwd;
int status = -1;
const char* ttyn,*p,*service;
const char * user = argv[1];
struct pam_conv pam_conv = {login_conv, argv[2]};

if (argc != 4)
{
printf("please inpute username and passwd\n");
_exit(0);
}
/* 初始化,并提供一个回调函数 */
status = pam_start(argv[3], user, &pam_conv, &pamh);

pam_get_item(pamh ,PAM_SERVICE ,(const void **)&service);
printf("Service is %s\n",service);

if (status != PAM_SUCCESS)
{
fprintf(stderr,"start error: %s\n", pam_strerror(pamh, status)); /* 显示错误原因 */
login_exit(1);
}
pam_get_item(pamh,PAM_USER,(const void **)&p);/*验证用户是否存在*/
if (getpwnam(p) == NULL)
{
printf("user does not exist\n");
_exit(0);
}
status = pam_authenticate(pamh, 0); /* 密码认证管理,检查用户输入的密码是否正确 */
if (status != PAM_SUCCESS)
{
fprintf(stderr,"authenticate error: %s\n", pam_strerror(pamh, status)); /* 显示错误原因 */
login_exit(1);
}
else
printf("authenticate success!\n");
getchar();
pam_end(pamh, PAM_SUCCESS); /* PAM事务的结束 */

}

/* 这个回调函数被PAM认证模块调用以便显示错误信息或者或者用来取得用户输入,采用图形界面的服务程序则应使用图形界面来取得 用户输入或显示提示信息*/
int login_conv(int num_msg, const struct pam_message **msg,
struct pam_response **response, void *appdata_ptr)
{
struct pam_message *m = (struct pam_message *)*msg;
struct pam_response *r ;
while (num_msg--)
{
switch (m->msg_style)
{
case PAM_PROMPT_ECHO_OFF:
r = (struct pam_response *)malloc(sizeof(struct pam_response));
r->resp = (char *)malloc(strlen((char*)appdata_ptr));
r->resp_retcode = 0;
strcpy(r->resp,(char*)appdata_ptr);
*response = r;
break;
case PAM_PROMPT_ECHO_ON:
(void) fputs(m->msg, stdout);
r->resp = (char*)malloc(PAM_MAX_RESP_SIZE);
fgets(r->resp, PAM_MAX_RESP_SIZE, stdin);
/* add code here to remove \n from fputs */
break;
case PAM_ERROR_MSG:
(void) fputs(m->msg, stderr);
break;
case PAM_TEXT_INFO:
(void) fputs(m->msg, stdout);
break;
}
}
return (PAM_SUCCESS);
}
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表