DoSERV技术专栏:浅析PAM认证机制(二)

四.基于PAM机制的应用程序

1.编写C源码

#include
#include
#include
#include
/* 文件pamtest.c

此程序从命令行接收一个用户名作为参数,然后对这个用户名进行auth和account验证

*/
// 定义一个pam_conv结构,用于与pam通信
       static struct pam_conv conv = {
           misc_conv,
           NULL
       };
// 主函数
       int main(int argc, char *argv[])
       {
           pam_handle_t *pamh=NULL;
           int retval;
           const char *user="nobody";
    const char *s1=NULL;

           if(argc == 2)
               user = argv[1];
    else
        exit(1);

           if(argc > 2) {
               fprintf(stderr, "Usage: pamtest0 [username]
");
               exit(1);
           }
    printf("user: %s
",user);
    retval = 0;

//调用pamtest配置文件
           retval = pam_start("pamtest", user, &conv, &pamh);

           if (retval == PAM_SUCCESS)

//进行auth类型认证
               retval = pam_authenticate(pamh, 0);    /* is user really user? */
    else {
//如果认证出错,pam_strerror将输出错误信息.
     printf("pam_authenticate(): %d
",retval);
     s1=pam_strerror( pamh, retval);
     printf("%s
",s1);
  }
           if (retval == PAM_SUCCESS)

//进行account类型认证
               retval = pam_acct_mgmt(pamh, 0);       /* permitted access? */
    else {
     printf("pam_acct_mgmt() : %d
",retval);
     s1=pam_strerror( pamh, retval);
     printf("%s
",s1);
  }
           /* This is where we have been authorized or not. */

           if (retval == PAM_SUCCESS) {
               fprintf(stdout, "Authenticated
");
           } else {
               fprintf(stdout, "Not Authenticated
");
           }

           if (pam_end(pamh,retval) != PAM_SUCCESS) {     /* close Linux-PAM */
               pamh = NULL;
               fprintf(stderr, "pamtest0: failed to release authenticator
");
               exit(1);
           }

           return ( retval == PAM_SUCCESS ? 0:1 );       /* indicate success */
       }
//END

2.编译

$ cc -o pamtest pamtest.c -lpam -lpam_misc -ldl

3.编写PAM配置文件

以root身份编辑/etc/pam.d/pamtest,并添加下面内容:

auth  required  /lib/security/pam_unix.so
account required /lib/security/pam_unix.so

4. 修改可执行程序权限

由于pam_unix.so需要访问/etc/shadow和/etc/passwd文件,所以要给pamtest文件附上SUID权限。

# chown root.root pamtest
# chmod 111 pamtest
# ls pamtest
# ls pamtest -hl
—s–x–x 1 root root 12K 2007-07-16 01:52 pamtest

5.执行

pamtest程序通过pam_unix.so,先对用户的密码进行验证,然后对用户的账号信息进行验证。以普通用户身份执行,输入错误的maj密码时。

maj@m2-u:01:52:09/var/tmp$ ./pamtest maj
user: maj
Password:
pam_acct_mgmt() : 7
Authentication failure
Not Authenticated
 
输入正确的密码时
 
maj@m2-u:01:54:44/var/tmp$ ./pamtest maj
user: maj
Password:
Authenticated
 
输入错误的root密码时
 
maj@m2-u:01:58:37/var/tmp$ ./pamtest root
user: root
Password:
pam_acct_mgmt() : 7
Authentication failure
Not Authenticated
maj@m2-u:01:59:15/var/tmp$
 
输入正确的root密码时
 
maj@m2-u:01:54:50/var/tmp$ ./pamtest root
user: root
Password:
Authenticated
maj@m2-u:01:58:37/var/tmp$