JavaScript is required to for searching.
跳过导航链接
退出打印视图
Oracle Solaris 11 开发者安全性指南     Oracle Solaris 11.1 Information Library (简体中文)
为本文档评分
search filter icon
search icon

文档信息

前言

1.  面向开发者的 Oracle Solaris 安全(概述)

2.  开发特权应用程序

特权应用程序

关于特权

管理员如何指定特权

如何实现特权

允许特权集合

可继承特权集合

有限特权集合

有效特权集合

超级用户与特权模型之间的兼容性

特权类别

使用特权进行编程

特权数据类型

特权接口

setppriv():用于设置特权

用于映射特权的 priv_str_to_set()

特权编码示例

包围在超级用户模型中的特权

包围在最小特权模型中的特权

特权应用程序开发指南

关于授权

3.  编写 PAM 应用程序和服务

4.  编写使用 GSS-API 的应用程序

5.  GSS-API 客户机示例

6.  GSS-API 服务器示例

7.  编写使用 SASL 的应用程序

8.  Oracle Solaris 加密框架介绍

9.  编写用户级加密应用程序

10.  Oracle Solaris 密钥管理框架介绍

A.  适用于开发者的安全编码准则

B.  基于 C 的 GSS-API 样例程序

C.  GSS-API 参考信息

D.  指定 OID

E.  SASL 示例的源代码

F.  SASL 参考信息表

词汇表

索引

请告诉我们如何提高我们的文档:
过于简略
不易阅读或难以理解
重要信息缺失
错误的内容
需要翻译的版本
其他
Your rating has been updated
感谢您的反馈!

您的反馈将非常有助于我们提供更好的文档。 您是否愿意参与我们的内容改进并提供进一步的意见?

使用特权进行编程

本节讨论使用特权的接口。要使用特权编程接口,需要以下头文件。

#include <priv.h>

本节还提供了说明如何在特权应用程序中使用特权接口的示例。

特权数据类型

以下是特权接口使用的主要数据类型:

特权接口

下表列出了使用特权的接口。表后面提供了一些主要特权接口的说明。

表 2-1 使用特权的接口

目的
函数
其他注释
获取和设置特权集合
setppriv()getppriv() 是系统调用。priv_ineffect()priv_set() 是为方便而使用的包装函数。
识别和转换特权
这些函数将指定的特权或特权集合映射到名称或编号。
处理特权集合
这些函数与特权内存分配、测试和各种设置操作有关。
获取和设置进程标志
PRIV_AWARE 进程标志指示进程是否了解特权或是否在超级用户模型下运行。PRIV_DEBUG 用于特权调试。
低级凭证处理
这些例程用于调试、底层系统调用和内核调用。

setppriv():用于设置特权

用于设置特权的主要函数为 setppriv(),该函数具有以下语法:

int setppriv(priv_op_t op, priv_ptype_t which, \
const priv_set_t *set);

op 表示要执行的特权操作。op 参数具有以下三个可能值之一:

which 用于指定要更改的特权集合类型:

set 指定要在更改操作中使用的特权。

此外,还提供了便利函数:priv_set()

用于映射特权的 priv_str_to_set()

这些函数便于使用其数值映射特权名称。priv_str_to_set() 是此系列中的典型函数。priv_str_to_set() 具有以下语法:

priv_set_t *priv_str_to_set(const char *buf, const char *set, \
const char **endptr);

priv_str_to_set() 采用 buf 中指定的特权名字符串。priv_str_to_set() 返回可以与四个特权集合之一组合的一组特权值。**endptr 可用于调试解析错误。

请注意,可以在 buf 中包括以下关键字:

特权编码示例

本节对使用超级用户模型和最小特权模型包围特权的方式进行比较。

包围在超级用户模型中的特权

以下示例说明如何在超级用户模型中包围特权操作。

示例 2-1 超级用户特权包围示例

/* Program start */
uid = getuid();
seteuid(uid);

/* Privilege bracketing */
seteuid(0);
/* Code requiring superuser capability */
...
/* End of code requiring superuser capability */
seteuid(uid);
...
/* Give up superuser ability permanently */
setreuid(uid,uid);

包围在最小特权模型中的特权

此示例说明如何在最小特权模型中包围特权操作。此示例使用以下假定:

代码后面是该示例的说明。


注 - 此示例的源代码也可以通过 Oracle 下载中心获取。请参见 http://www.oracle.com/technetwork/indexes/downloads/sdlc-decommission-333274.html


示例 2-2 最小特权包围示例

1  #include <priv.h>
2  /* Always use the basic set. The Basic set might grow in future
3   * releases and potentially retrict actions that are currently
4   * unrestricted */
5  priv_set_t *temp = priv_str_to_set("basic", ",", NULL);

6  /* PRIV_FILE_DAC_READ is needed in this example */
7  (void) priv_addset(temp, PRIV_FILE_DAC_READ);

8  /* PRIV_PROC_EXEC is no longer needed after program starts */
9  (void) priv_delset(temp, PRIV_PROC_EXEC);

10 /* Compute the set of privileges that are never needed */
11  priv_inverse(temp);

12  /* Remove the set of unneeded privs from Permitted (and by
13   * implication from Effective) */
14  (void) setppriv(PRIV_OFF, PRIV_PERMITTED, temp);

15  /* Remove unneeded priv set from Limit to be safe */
16  (void) setppriv(PRIV_OFF, PRIV_LIMIT, temp);

17  /* Done with temp */
18  priv_freeset(temp);

19  /* Now get rid of the euid that brought us extra privs */
20  (void) seteuid(getuid());

21  /* Toggle PRIV_FILE_DAC_READ off while it is unneeded */
22  priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_FILE_DAC_READ, NULL);

23  /* Toggle PRIV_FILE_DAC_READ on when special privilege is needed*/
24  priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_FILE_DAC_READ, NULL);

25  fd = open("/some/retricted/file", O_RDONLY);

26  /* Toggle PRIV_FILE_DAC_READ off after it has been used */
27  priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_FILE_DAC_READ, NULL);

28  /* Remove PRIV_FILE_DAC_READ when it is no longer needed */
29  priv_set(PRIV_OFF, PRIV_ALLSETS, PRIV_FILE_DAC_READ, NULL);

该程序定义了名为 temp 的变量。temp 变量确定此程序不需要的特权集合。最初,在第 5 行将 temp 定义为包含基本特权集合。在第 7 行将 file_dac_read 特权添加到 temp 中。proc_exec 特权对 exec(1) 新进程(在此程序中不允许)是必需的。因此,在第 9 行中从 temp 中删除了 proc_exec,从而使 exec(1) 命令无法执行新进程。

此时,temp 仅包含该程序所需的那些特权,即基本集合加上 file_dac_read ,再删除 proc_exec。在第 11 行中,priv_inverse () 函数将计算 temp 的逆向值,并将 temp 的值重置为补值。逆向值是从所有可能特权集合中删除指定集合(在本例中为 temp)所得的结果。作为第 11 行的结果, temp 现在包含该程序永不使用的那些特权。在第 14 行中,从允许集合中删除了 temp 定义的不需要的特权。此删除操作还从有效集合中有效地删除了这些特权。在第 16 行中,从有限集合中删除了不需要的特权。在第 18 行中,因为不再需要 temp,因而释放了 temp 变量。

该程序可以识别特权。因此,该程序不使用 setuid,但可以将有效的 UID 重置为第 20 行中的用户的实际 UID。

在第 22 行中,通过从有效集合中删除 file_dac_read 特权禁用了该特权。在实际的程序中,需要 file_dac_read 特权之前,还将发生其他活动。在该样例程序中,读取第 25 行中的文件需要 file_dac_read。因此,在第 24 行中,启用了 file_dac_read。读取文件后,将再次从有效集合中立即删除 file_dac_read。读取所有文件后,通过在所有特权集合中禁用 file_dac_read ,可永久地删除 file_dac_read

下表说明了随着程序的运行如何转换特权集合。已指出了行号。

表 2-2 特权集合转换

步骤
temp 集合
允许特权集合
有效特权集合
有限特权集合
最初
所有
所有
所有
第 5 行-将 temp 设置为基本特权
基本
所有
所有
所有
第 7 行-将 file_dac_read 添加到 temp 中。
基本 + file_dac_read
所有
所有
所有
第 9 行-从 temp 中删除了 proc_exec
基本 + file_dac_readproc_exec
所有
所有
所有
第 11 行-temp 重置为逆向值。
所有-(基本 + file_dac_readproc_exec)
所有
所有
所有
第 14 行-在允许集合中禁用不需要的特权。
所有-(基本 + file_dac_readproc_exec)
基本 + file_dac_readproc_exec
基本 + file_dac_readproc_exec
所有
第 16 行-在有限集合中禁用不需要的特权。
所有-(基本 + file_dac_readproc_exec)
基本 + file_dac_readproc_exec
基本 + file_dac_readproc_exec
基本 + file_dac_readproc_exec
第 18 行-释放了 temp 文件。
基本 + file_dac_readproc_exec
基本 + file_dac_readproc_exec
基本 + file_dac_readproc_exec
第 22 行-禁用 file_dac_read 直到需要时再启用。
基本 - proc_exec
基本 - proc_exec
基本 + file_dac_readproc_exec
第 24 行-需要时启用 file_dac_read
基本 + file_dac_readproc_exec
基本 + file_dac_readproc_exec
基本 + file_dac_readproc_exec
第 27 行-执行 read() 操作后禁用 file_dac_read
基本 - proc_exec
基本 - proc_exec
基本 + file_dac_readproc_exec
第 29 行-不再需要 file_dac_read 时,从所有集合中删除该特权。
基本 - proc_exec
基本 - proc_exec
基本 - proc_exec