PAM(4)

news/2024/10/21 23:13:02/

有了前面的知识,今天将和大家一起写一个简单的PAM模块

好了废话不说了直接写吧(文件为 pam_test.c)

[cpp]  view plain  copy
  1. #define PAM_SM_AUTH  
  2. #include <security/pam_modules.h>  
  3. #include <security/pam_appl.h>  
  4. #include <stdio.h>  
  5. #include <string.h>  
  6. #include <stdarg.h>  
  7.   
  8. #define MODULE_NAME "pam_sample"  
  9. #define SAMPLE_PROMPT "Extra Password for root:"  
  10. #define PAM_DEBUG_ARG      1  
  11.   
  12. #define DPRINT if (ctrl & PAM_DEBUG_ARG) sample_syslog  
  13.   
  14. #define PAM_RET_CHECK(ret) if(PAM_SUCCESS != ret) \  
  15.                            {                        \  
  16.                                 return ret;         \  
  17.                            }  
  18.   
  19.   
  20.   
  21. //if debug is setting this function can write log information /var/log/message  
  22. static void sample_syslog(int err, const char *format, ...)  
  23. {  
  24.     va_list args;  
  25.     char buffer[1024];  
  26.   
  27.     va_start(args, format);  
  28.     vsprintf(buffer, format, args);  
  29.     /* don't do openlog or closelog, but put our name in to be friendly */  
  30.     syslog(err, "%s: %s", MODULE_NAME, buffer);  
  31.     va_end(args);  
  32. }  
  33.   
  34. //get the paramters  
  35. static int sample_parse(int argc, const char **argv, char *szconf)  
  36. {  
  37.   int ctrl=0;  
  38.     
  39.   /* 
  40.    *  If either is not there, then we can't parse anything. 
  41.    */  
  42.   if ((argc == 0) || (argv == NULL)) {  
  43.     return ctrl;  
  44.   }  
  45.     
  46.   /* step through arguments */  
  47.   for (ctrl=0; argc-- > 0; ++argv)   
  48.   {  
  49.       
  50.     /* generic options */  
  51.     if (!strcmp(*argv, "debug"))   
  52.     {  
  53.       ctrl |= PAM_DEBUG_ARG;  
  54.     }  
  55.     else   
  56.     {  
  57.      sample_syslog(LOG_WARNING, "unrecognized option '%s'", *argv);  
  58.     }  
  59.   }  
  60.   return ctrl;  
  61. }  
  62.   
  63. //callback function to release a buffer  
  64. void sample_pam_free(pam_handle_t *pamh, void *pbuf, int error_status)  
  65. {  
  66.     free(pbuf);  
  67. }  
  68. //conversation function  
  69. //这个是做了封装的对话函数,每次只允许你向应用程序请求一个"问题"  
  70. int sample_converse(pam_handle_t *pamh, int msg_style, char *message, char **password)  
  71. {  
  72.     const struct pam_conv *conv;  
  73.       
  74.     struct pam_message resp_message;  
  75.     const struct pam_message *msg[1];  
  76.     struct pam_response *resp = NULL;  
  77.       
  78.     int retval;  
  79.   
  80.     resp_message.msg_style = msg_style;  
  81.     resp_message.msg = message;  
  82.     msg[0] = &resp_message;  
  83.     //之前老提到对话函数,我们说过对话函数由应用程序提供,这里可以看到在模块中怎么获得对话函数  
  84. //通过pam_get_item 可以获得pam_conv这个结构的一个指针(第二个参数是PAM_CONV表示类型)  
  85. //然后就想下面的调用方式,你可以在你的模块中调用这个对话函数,和应用程序交互  
  86.     retval = pam_get_item(pamh, PAM_CONV, (const void **)&conv);  
  87.     PAM_RET_CHECK(retval)  
  88.           
  89.     retval = conv->conv(1, msg, &resp, conv->appdata_ptr);  
  90.     PAM_RET_CHECK(retval)  
  91.     if(password)  
  92.     {  
  93.         *password = resp->resp;  
  94.         free(resp);  
  95.     }  
  96.       
  97.     return PAM_SUCCESS;  
  98. }   
  99.   
  100.   
  101. #ifdef PAM_SM_AUTH  
  102. PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)  
  103. {  
  104.     char *puser, *ppwd;  
  105.     int nret;  
  106.     int nloop;  
  107.     int nChallenge;  
  108.     int nValidrsp;  
  109.     char szbuf[256];  
  110.     char szconf[256];  
  111.     char *resp2challenge = NULL;  
  112.   
  113.     int ctrl = 0;  
  114.     memset(szconf, 0, 256);  
  115. //通过这个函数获得用户名  
  116.     nret = pam_get_user(pamh, &puser, "UserName:");  
  117.     if(PAM_SUCCESS != nret)  
  118.     {  
  119.         int *pret = (int *)malloc(sizeof(int));  
  120.         //makelog("get username failed");  
  121.         DPRINT(LOG_DEBUG, "Get user name failed");  
  122.         *pret = nret;  
  123.         pam_set_data(pamh, "sample_setcred_return", (void *)pret, sample_pam_free);  
  124.         return PAM_SYSTEM_ERR;  
  125.     }  
  126.     else  
  127.     {  
  128.         //username  
  129. //如果用户名为root,请用户输入附加密码 "123456"  
  130.         if(!strcasecmp("root", puser))  
  131. {  
  132. //如果为root 和应用程序交互,让用户输入密码  
  133. //如果为root 和应用程序交互,让用户输入密码  
  134. nret = sample_converse(pamh, PAM_PROMPT_ECHO_OFF, SAMPLE_PROMPT, &ppwd);  
  135. if(PAM_SUCCESS != nret)  
  136. {  
  137.     int *pret = (int *)malloc(sizeof(int));  
  138.      *pret = nret;  
  139.      DPRINT(LOG_DEBUG, "Get extra password failed");  
  140.      pam_set_data(pamh, "sample_setcred_return", (void *)pret, sample_pam_free);  
  141.       return nret;  
  142. }  
  143. //you have get the extra password  
  144. if(strcasecmp("123456", ppwd))  
  145. {  
  146.     int *pret = (int *)malloc(sizeof(int));                          *pret = PAM_AUTH_ERR;                          DPRINT(LOG_DEBUG, "Invalid extra password");                          pam_set_data(pamh, "sample_setcred_return", (void *)pret, sample_pam_free);                          return PAM_AUTH_ERR;  
  147. }  
  148. }  
  149. }  
  150.     return PAM_SUCCESS;  
  151. }  
  152.   
  153. PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv)  
  154. {  
  155.     int nret = PAM_SUCCESS, *pret;  
  156.     pret = &nret;  
  157.     pam_get_data(pamh, "sample_setcred_return", (void **)&pret);  
  158.     return *pret;  
  159. }  
  160.   
  161. #endif//PAM_SM_AUTH  


 

编译 gcc -o pam_test.so -shared -fPIC ./pam_test.c -lpam

将pam_test.so 拷贝到/lib/security/下(平台不同有差异)

配置 vim /etc/pam.d/login (如果想为login使用这个模块) 

在你希望的位置添加 auth sufficient pam_test.so

sufficient 还可以为 required 等具体请参照http://www.ibm.com/developerworks/cn/linux/l-pam/index.html?ca=drs-#resources

至此一个简单的PAM模块就写好了

 


http://www.ppmy.cn/news/345136.html

相关文章

PAM(一)

学着写PAM 模块之前了解下PAM的大致情况是不错的选择(也是必须的),所以这里也只好引用一下关于PAM简介的内容了 原文地址&#xff1a;http://blog.csdn.net/yyyyangyang/article/details/6589086 一、什么是PAM PAM(Pluggable Authentication Modules)可插拔认证模块,最初是有S…

McPAT

McPAT: An Integrated Power, Area, and Timing Modeling Framework for Multicore and Manycore Architectures 论文的参与单位&#xff1a;美国圣母大学&#xff0c;惠普实验室&#xff0c;国立首尔大学&#xff0c;圣迭戈加利福尼亚大学 摘要&#xff1a; McPAT&#xff1a…

使用 Terraform 在 GCP 上一键部署 EMQX MQTT Broker

引言 MQTT 是一种轻量级的消息传递协议&#xff0c;适用于物联网应用实现设备间通信。 作为一款主流的开源 MQTT Broker&#xff0c;EMQX 能够提供高扩展性、可靠性和安全性的 MQTT 消息传递服务。 借助广泛应用的基础设施即代码&#xff08;IaC&#xff09;工具 Terraform&a…

PA

About the manual 数据包加速器&#xff08;PA&#xff09;是网络协处理器&#xff08;NETCP&#xff09;外设的主要组件之一。该PA与安全加速器&#xff08;SA&#xff09;和千兆位以太网交换机子系统一起形成网络处理解决方案。NETCP中PA的目的是执行数据包处理操作&#xff…

Linux中pam模块详解

pam简介 Linux-PAM(linux可插入认证模块)是一套共享库&#xff0c;使本地系统管理员可以随意选择程序的认证方式。换句话说&#xff0c;不用重新编译一个包含PAM功能的应用程序&#xff0c;就可以改变它使用的认证机制。这种方式下,就算升级本地认证机制,也不用修改程序. PAM使…

PAM(3)

写到这一篇才发现自己了解的远没有预期的多.. 上一次说了对话函数,对话函数是PAM模块与使用PAM进行认证的应用程序进行信息交互的桥梁,通过对话函数PAM模块可以获得用户的输入信息(明文、密文)&#xff0c; 还有两套很重要的函数 pam_set_data(pam_handle_t *pamh, const char …

podman简介

podman简介掌握docker,跟上云时代的步伐 Podman是一个开源项目&#xff0c;可在大多数Linux平台上使用并开源在GitHub上。Podman是一个无守护进程的容器引擎&#xff0c;用于在Linux系统上开发&#xff0c;管理和运行Open Container Initiative&#xff08;OCI&#xff09;容器…

Impala

应用场景 在使用Hive的过程中,编写了HQL语句,发现HQL执行过程是非常慢的,因为hive采用的是把HQL转化成hadoop的MapReduce任务,然后编译,打包成jar包,分发到各个server上去执行,这个过程会很慢很慢!而impala也可以执行SQL,但是比Hive快很多,而Impala根本不用Hadoop的M…