2.1. 获取和设置 PAM_ITEM 和数据

首先,我们介绍了* Linux-PAM 库和 Linux-PAM *感知应用程序对模块的期望。本质上,这是libpam.*库。

2.1.1. 设置模块内部数据

#include <security/pam_modules.h> 
   int pam_set_data( 
   pamh,  
   module_data_name,  
   data,  
   (*cleanup)(pam_handle_t *pamh, void *data, int error_status)); 
 pam_handle_t *pamh; 
 const char *module_data_name; 
 void *data; 
 void (*cleanup)(pam_handle_t *pamh, void *data, int error_status); 

2.1.1.1. DESCRIPTION

pam_set_data函数将一个对象的指针与* pamh 参数指定的 PAM 上下文中的(希望)唯一字符串 module_data_name *相关联。

PAM 模块可以是可动态加载的对象。通常,此类文件不应包含* static 变量。该函数及其对应的 pam_get_data(3)为模块提供了一种机制,可将某些数据与句柄 pamh 关联。通常,模块将调用pam_set_data函数以(希望)唯一的 module_data_name 注册一些数据。数据也可以供其他模块使用,但不能被应用程序使用。由于此函数仅存储指向 data *的指针,因此模块不应修改或释放其内容。

函数cleanup()与* data *相关联,如果非 NULL,则当该数据被覆盖或在调用 pam_end(3)之后被调用。

2.1.1.2. 返回值

2.1.2. 获取模块内部数据

#include <security/pam_modules.h> 
   int pam_get_data( 
   pamh,  
   module_data_name,  
   data); 
 const pam_handle_t *pamh; 
 const char *module_data_name; 
 const void **data; 

2.1.2.1. DESCRIPTION

此函数与 pam_set_data(3)函数一起用于 Management 仅对调用 PAM 模块有意义的模块特定数据。

pam_get_data函数在* pamh 参数指定的 PAM 上下文中查找与(希望)唯一字符串 module_data_name 关联的对象。成功调用pam_get_data将导致 data *指向对象。注意,该数据不是副本,应被模块视为常量。

2.1.2.2. 返回值

2.1.3. 设置 PAM 项目

#include <security/pam_modules.h> 
   int pam_set_item( 
   pamh,  
   item_type,  
   item); 
 pam_handle_t *pamh; 
 int item_type; 
 const void *item; 

2.1.3.1. DESCRIPTION

pam_set_item功能允许应用程序和 PAM 服务模块访问和更新* item_type 的 PAM 信息。为此,将创建 item 参数指向的对象的副本。支持以下 item_type *:

通常,应用程序或模块将尝试提供经过最强身份验证的值(本地帐户先于远程帐户)。对该值的信任级别体现在与应用程序关联的实际身份验证堆栈中,因此最终位于系统 Management 员的酌处权。

以下附加项目特定于 Linux-PAM,不应在可移植应用程序中使用:

对于除* PAM_CONV 和 PAM_FAIL_DELAY 之外的所有* item_type item 是指向\ 终止的字符串的指针。对于 PAM_CONV, item 指向已初始化的 pam_conv 结构。对于 PAM_FAIL_DELAY, item *是函数指针:void (*delay_fn)(int retval, unsigned usec_delay, void *appdata_ptr)

返回到应用程序之前,PAM_AUTHTOK 和 PAM_OLDAUTHTOK 都将被重置。这意味着应用程序无法访问身份验证令牌。

2.1.3.2. 返回值

2.1.4. 获取 PAM 项目

#include <security/pam_modules.h> 
   int pam_get_item( 
   pamh,  
   item_type,  
   item); 
 const pam_handle_t *pamh; 
 int item_type; 
 const void **item; 

2.1.4.1. DESCRIPTION

pam_get_item功能允许应用程序和 PAM 服务模块访问和检索* item_type 的 PAM 信息。成功返回后, item 包含一个指向相应项目值的指针。注意,这是指向实际数据的指针,并且不应 free()*编辑或覆盖! * item_type *支持以下值:

通常,应用程序或模块将尝试提供经过最强身份验证的值(本地帐户先于远程帐户)。对该值的信任级别体现在与应用程序关联的实际身份验证堆栈中,因此最终位于系统 Management 员的酌处权。

以下附加项目特定于 Linux-PAM,不应在可移植应用程序中使用:

如果服务模块希望获取用户名,则不应使用此功能,而应执行对 pam_get_user(3)的调用。

仅服务模块有权读取身份验证令牌 PAM_AUTHTOK 和 PAM_OLDAUTHTOK。

2.1.4.2. 返回值

2.1.5. 获取用户名

#include <security/pam_modules.h> 
   int pam_get_user( 
   pamh,  
   user,  
   prompt); 
 const pam_handle_t *pamh; 
 const char **user; 
 const char *prompt; 

2.1.5.1. DESCRIPTION

pam_get_user函数返回由 pam_start(3)指定的用户名。如果未指定用户,则返回pam_get_item (pamh, PAM_USER, ... );返回的内容。如果为 NULL,则通过 pam_conv(3)机制获取用户名,并使用以下列表中的第一个非 NULL 字符串提示用户:

无论通过哪种方式获得用户名,都将返回指向它的指针作为** user 的内容。请注意,此内存不应由模块“释放”()或“修改” *。

此函数设置与 pam_set_item(3)和 pam_get_item(3)函数关联的* PAM_USER *项目。

2.1.5.2. 返回值

2.1.6. 对话功能

#include <security/pam_appl.h>
struct pam_message {
    int msg_style;
    const char *msg;
};

struct pam_response {
    char *resp;
    int resp_retcode;
};

struct pam_conv {
    int (*conv)(int num_msg, const struct pam_message **msg,
                struct pam_response **resp, void *appdata_ptr);
    void *appdata_ptr;
};

2.1.6.1. DESCRIPTION

PAM 库使用应用程序定义的回调来允许已加载的模块与应用程序之间的直接通信。该回调由在事务开始时传递给 pam_start(3)的* struct pam_conv *指定。

当模块调用引用的 conv()函数时,参数* appdata_ptr *被设置为该结构的第二个元素。

调用 conv()的其他参数涉及模块和应用程序交换的信息。也就是说,* num_msg 保持指针数组 msg 的长度。成功返回后,指针 resp 指向 pam_response 结构的数组,其中包含应用程序提供的文本。该结构的 resp_retcode 成员未使用,应设置为零。调用者有责任使用 free(3)释放此数组和响应本身。注意,* resp struct pam_response *数组,而不是指针数组。

响应数始终等于* num_msg *对话函数参数。这确实要求在每次调用会话函数之后,响应数组都必须是 free(3)。响应的索引直接对应于 pam_message 数组中的提示索引。

失败时,对话功能应释放其已分配的所有资源,并返回 sched 义的 PAM 错误代码之一。

每个消息可以具有四种类型之一,由* struct pam_message msg_style *成员指定:

拥有消息数组的意义在于,有可能在一次来自模块的调用中将许多东西传递给应用程序。对于应用程序来说,关联的事物一下子出现也很方便:基于 Windows 的应用程序可以立即呈现一个带有许多消息/提示的表单。

顺便说一句,值得注意的是,Linux-PAM 处理 const struct pam_message msg 对话函数参数的方式与 Solaris 的 PAM(以及派生的产品,包括 HP/UX)之间存在差异.?).Linux-PAM 将 msg 参数解释为完全等同于以下原型 const struct struct pam_message * msg [](从本质上讲,它与熟悉的 main()函数的 argv 参数的常用原型一致:char argv;和 char * argv [])。换句话说,Linux-PAM 将 msg 参数解释为指向 num_msg 只读数组“ struct pam_message”的指针的指针。 Solaris 的 PAM 实现将此参数解释为指向 num_msg pam_message 结构数组的指针。幸运的是,对于大多数模块/应用程序开发人员而言,当 num_msg 的值为 1 时,这两个定义是完全等效的。不幸的是,随便将此数字增加到两个会导致意外的兼容性问题。

试图维持两种 PAM 实现与源代码级兼容性的两个已知模块编写器变通办法有何价值:

msg[n] = & (( *msg )[n])

2.1.6.2. 返回值

2.1.7. 设置或更改 PAM 环境变量

#include <security/pam_appl.h> 
   int pam_putenv( 
   pamh,  
   name_value); 
 pam_handle_t *pamh; 
 const char *name_value; 

2.1.7.1. DESCRIPTION

pam_putenv函数用于添加或更改与* pamh *句柄关联的 PAM 环境变量的值。

pam_putenv()对* name_value *的副本进行操作,这意味着与 putenv(3)相比,应用程序负责释放数据。

2.1.7.2. 返回值

2.1.8. 获取一个 PAM 环境变量

#include <security/pam_appl.h> 
   const char *pam_getenv( 
   pamh,  
   name); 
 pam_handle_t *pamh; 
 const char *name; 

2.1.8.1. DESCRIPTION

pam_getenv函数在与句柄* pamh 关联的 PAM 环境列表中搜索与 name *所指向的字符串匹配的项,并返回指向环境变量值的指针。该应用程序不允许释放数据。

2.1.8.2. 返回值

pam_getenv函数在失败时返回 NULL。

2.1.9. 获取 PAM 环境

#include <security/pam_appl.h> 
   char **pam_getenvlist( 
   pamh); 
 pam_handle_t *pamh; 

2.1.9.1. DESCRIPTION

pam_getenvlist函数返回与句柄* pamh *关联的 PAM 环境的完整副本。 PAM 环境变量表示授予服务时已认证用户的常规环境变量的内容。

内存的格式是 malloc()的 char 指针数组,其最后一个元素设置为 NULL。该数组中的每个非 NULL 条目都指向一个 NUL 终止且 malloc()的 char 字符串,其形式为“ * name = value *”。

应该注意的是,此内存永远不会由 libpam 释放。一旦通过调用pam_getenvlist获得,调用应用程序有责任释放()该内存。

返回的数组的格式和内容是设计使然,而不是巧合,与 execle(3)函数调用的第三个参数所需的格式和内容相匹配。

2.1.9.2. 返回值

pam_getenvlist函数在失败时返回 NULL。

上一章 首页 下一章