科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件Apache中的进程剖析(2)

Apache中的进程剖析(2)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

本文介绍了Apache中对Unix进程和Window进程的封装,在阅读这部分内容之前必须具有以下基本知识:

作者:tingya 来源:CSDN 2008年3月26日

关键字: 剖析 进程 Apache 开源

  • 评论
  • 分享微博
  • 分享邮件
6.1.2.2Window平台
相比于Unix下的apr_procattr_t结构,Window下的该结构定义要简单一些,它定义在Unix下的进程属性结构定义在srclib\apr\include\arch\win32\apr_arch_threadproc.h中,如下:
struct apr_procattr_t {
    apr_pool_t *pool;
 
    /*Part 1*/
    apr_file_t *parent_in;
    apr_file_t *child_in;
    apr_file_t *parent_out;
    apr_file_t *child_out;
    apr_file_t *parent_err;
    apr_file_t *child_err;
 
    /*Part 2*/
    char *currdir;
    apr_int32_t cmdtype;
    apr_int32_t detached;
    apr_child_errfn_t *errfn;
    apr_int32_t errchk;
 
    /*Part 3*/
    HANDLE     user_token;
    LPSECURITY_ATTRIBUTES   sa;
    LPVOID                  sd;
};
Window中该结构包含三方面的内容:
      第一部分
该部分与Unix中的功能相同,描述了父进程和子进程之间通信的三个管道文件:一个管道用于从父进程写入数据,从子进程中读出;一个管道用于从子进程写入数据,从父进程中读出;一个管道负责子进程写入错误信息通知父进程。与Unix类似,Window中的管道创建可以使用apr_procattr_io_set统一创建,也可以使用apr_procattr_child_in_set单独创建。apr_procattr_io_set函数实现如下:
APR_DECLARE(apr_status_t) apr_procattr_io_set(apr_procattr_t *attr,
                                              apr_int32_t in,
                                              apr_int32_t out,
                                              apr_int32_t err)
{
    apr_status_t stat = APR_SUCCESS;
 
    if (in) {
        if (in == APR_CHILD_BLOCK)
            in = APR_READ_BLOCK;
        else if (in == APR_PARENT_BLOCK)     u
            in = APR_WRITE_BLOCK;
        stat = apr_create_nt_pipe(&attr->child_in, &attr->parent_in, in,
                                 attr->pool);
        if (stat == APR_SUCCESS)
            stat = apr_file_inherit_unset(attr->parent_in);
    }
    if (out && stat == APR_SUCCESS) {
        stat = apr_create_nt_pipe(&attr->parent_out, &attr->child_out, out,
                                  attr->pool); v
        if (stat == APR_SUCCESS)
            stat = apr_file_inherit_unset(attr->parent_out);
    }
    if (err && stat == APR_SUCCESS) {
        stat = apr_create_nt_pipe(&attr->parent_err, &attr->child_err, err,
                                  attr->pool); w
        if (stat == APR_SUCCESS)
            stat = apr_file_inherit_unset(attr->parent_err);
    }
    return stat;
}
在Window下,管道的创建通过内部函数apr_create_nt_pipe实现,具体的创建细节我们在第七章的”管道章节”会详细描述。不过在Window管道中,
      第二部分
      第三部分
第三部分的内容是Window所独有的,主要用于Window的安全性。为了了解这几个成员的真实含义,我们必须对Window 的安全性有一定的了解。
首先我们来看use_token,它是一个HANDLE类型,表示用户的访问令牌。与Window9X系列操作系统相比,Window NT以上的版本的安全性都得到了极大的提高。在Windows中,安全性是指将对象所受的保护与用户的访问权进行比较。如果用户拥有足够的访问权(访问权等于或超过对象所受的保护),则用户能够使用这个对象。在Windows 的文档中将对象所受保护的级别称作安全描述符(securitydescriptor),这是一种结构,它能告诉安全系统:用户需要什么样的权力才能访问这个对象;而用户则有一个访问令牌(Access),它是另一种结构,它能告诉安全系统:在一个给定的位置,用户有什么样的访问权。令牌包括多方面的内容:用户安全标示符(SID)、组SID列表、特权列表和模拟(Impersonating)信息,可以用下图描述:
Token

用户将访问令牌交给Windows NT系统,并以此获得对对象的访问。当用户登录系统时,Windows NT/2000 将验证他的密码,如果用户验证成功,系统产生一个访问令牌。该用户启动的任何进程都将附加该令牌,访问令牌代表进程的安全环境,它控制了进程与可保护对象(securable object)的交互。当进程访问一个可保护对象时,系统将该对象的访问控制列表(ACL)中的每个访问控制项(ACE)和访问令牌中的 SID 进行比较以确定进程是否可以访问该对象。由于用户启动的任何进程都将附加该用户的访问令牌,因此任何进程都知道用户的 SID 并且可以访问它。
Window中不同的用户登录所产生的访问令牌是不一样的,因此它们的访问权限也不一样。在Window中大部分服务进程都是以本地系统帐户(local system)运行的,这是一个特殊的帐户,所以以本地系统帐户运行的进程和普通进程不同之处在于:
1) 注册表的 HKEY_CURRENT_USER 键是和缺省用户而不是当前用户相联系的,要访问其他用户的配置文件,需要先模拟该用户,然后再访问 HKEY_CURRENT_USER 。
2) 可以打开 HKEY_LOCAL_MACHINE\SECURITY 注册表键
3) 该进程不能访问网络资源,如共享、管道,因为它不能提供信任凭证,而只能使用空连接。 在 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters 处的 NullSessionPipes 和 NullSessionShares 的值指明了可以被空连接访问的管道和共享。
或者也可以设置 RestrictNullSessAccess = 0,以允许空连接的用户访问该计算机上的所有管道和共享。(呵呵,这个是个安全隐患哦,可不要干呀。上边两个值最好也全都设成空)
4) 不能和其他程序共享对象,除非在创建对象时设置 DACL 允许用户访问。
5) 如果启动命令行提示符来运行批处理文件,用户可以按 Ctrl+C 来终止批处理的运行,并且用户就获得了一个 Local System 权限的 shell。
正是由于服务程序运行在权限极大的 Local System 账号下,如果网络客户也使用该账号来访问系统将给系统带来安全隐患,因此 NT/2000 提供了模拟功能 --- 服务程序在处理客户请求时使用一个权限较低的客户身份运行,处理完客户请求再恢复。user_token则用于指定模拟的用户。不过Window中并不是直接使用字符串类型来描述账户。由于每一个账户都对应一个访问令牌,因此,window总是使用访问令牌标记模拟的用户。不过APR中提供了从用户名到访问令牌的转换函数apr_procattr_user_set。apr_proc_attr_user_set的实现细节我们在下一章描述。
如果user_token指定,那么在创建进程的时候,APR将使用该模拟用户创建进程。创建的过程我们在进程创建章节描述。

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章