• 实际用户ID和有效用户ID (一) *****


    在Unix进程中涉及多个用户ID和用户组ID,包括如下:

      1、实际用户ID和实际用户组ID:标识我是谁,身份的识别,谁运行的程序。也就是登录用户的uid和gid,比如我的Linux以simon登录,在Linux运行的所有的命令的实际用户ID都是simon的uid,实际用户组ID都是simon的gid(可以用id命令查看)。

      2、有效用户ID和有效用户组ID:进程用来决定我们对资源的访问权限,权利的识别。一般情况下,有效用户ID等于实际用户ID,有效用户组ID等于实际用户组ID。

        当设置(SUID)位,则有效用户ID等于文件的所有者的uid;同样,如果设置了(SGID)位,则有效用户组ID等于文件所有者的gid。

    进程的RealUID和EffectiveUID 以及进程UID的继承关系

    1. 身份的标识: Real UID

        * 进程的UID只是泛称, 其实有很多种UID

        * 进程的 Real UID 是进程身份的标识, 用来说明Who am I, 没有实权

        * 进程能做什么 不是有 RealUID来决定的

    2. 权利的标识: Effective UID

        * 有身份无权利是不行的, 有权利才能为所欲为

        * Effective UID 是进程的权利的标识, 标识了该进程的“权利”

        * Linux的授权 是 靠 Effective UID 来识别的

        * 有权利就能做一切

        * 之前说明的,文件、资源以及特权API操作权限 是 通过 Effective UID来识别的

    3. 身份和权利的关系

        * 默认情况下 Real UID == Effective UID, 所以使用ps命令输出的 就是 Effective UID

        * 我们也可以显示完整的 Effective UID 和Real UID

       

    4. ROOT 用户的特权

        * Root 用户, 均是指 Effective UID == ROOT的进程

        * 不受任何限制,可以为所欲为

        * ROOT进程可以调用setUID 修改自己的Real UID,它也可以把自己的Effective UID改为普通的UID

    5. UID的世袭

        * 在Linux世界里,为了安全考虑,UID世袭规则: 身份可以世袭,权利不能世袭

        * 子进程的 Real UID = Effective UID,  继承 父进程的Real UID

              若父进程的Effective UID 与 Real UID 不一样,则不具有父进程的权利

    四、文件的setUID -- 文件的setUID标志以及其作用。

    1. 平民身份,皇族特权(ROOT权限)  需求及解决

        1.1  需求:

            * Linux的passwd是一个可执行程序, 用于修改用户的密码

            * passwd需要修改多用户的账号文件(该文件仅能ROOT用户可以读写)

            * 但是 普通用户 也要修改自己的密码

            * passwd虽然 是平民身份(由普通用户启动),但是却需要皇族的权限  ---- 身份 和 权利不同

        1.2 解决:

           * 临时替身进程的Effective UID, 而维持身份不变(Real UID), 让他能够利用特权,而又不传给子进程

    2. Linux的文件的setUID的标志

        文件的Owner UID设置为特权用户(如ROOT)

        文件面向 Owner UID的群体和操作权限 增加额外的setUID标志

        Linux系统保证,任何用户(进程)执行该文件时(Fork一个新的进程来加载该可执行文件),子进程的Real UID仍然继承起父进程的RealUID, Effective UID 却被提升 到特权UID

        

        setUID的前提是可执行文件,其他文件不能setUID

        rws,用s替代了x;而且s包含了x

    3. chmod设置setUID的方式

        chmod 4775 test.txt    4就是特殊的设置方法

        chmod 0775 test.txt    0可以清楚该标志

        chmod u+s test.txt 也具有相同的效果

        chmod u-s test.txt

    4. setUID的安全问题

        setUID的进程的EUID提升了, RUID没有提升

        但是如果该进程为自己正身(将自己的RUID改成了和EUID一样的)了, 它的所有子进程都具有了该特殊权限

         passwd没有正身

        Android将自己的su 正身了

    5. 有RealGID, EffectiveGID, setGID吗

        答案是存在

    详细分析如下:

    以上来自:APUE(《高级UNIX环境编程》)

    Unix系统通过进程的有效用户ID和有效用户组ID来决定进程对系统资源的访问权限。

    以上这些概念还是比较的抽象,那么下面写一个小的测试程序:

    #include <stdio.h>                                                                                                                                         
    #include <unistd.h>
    #include <sys/types.h>
    
    int main(void)
    {
                printf("uid=%d, gid=%d, euid=%d, egid=%d
    ", getuid(), getgid(), geteuid(), getegid());
                //sleep(10);
    }

    这个程序非常简单没有什么好说的。我们编译这个程序生成test 程序 

    jiangzhaowei@kitking:~/share/test$ id
    uid=1000(jiangzhaowei) gid=1000(jiangzhaowei) groups=1000(jiangzhaowei),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),108(lxd),999(docker)
    jiangzhaowei@kitking:~/share/test$ ./test 
    uid=1000, gid=1000, euid=1000, egid=1000

      通过id命令看到当前登录用户为jiangzhaowei,uid=1000,gid=1000。通过ls命令我们可以看出test程序没有设置SUID和SGID,所有者是jiangzhaowei,所有组也是jiangzhaowei。执行test我们发现有效用户ID等于实际用户ID(1000),有效用户组ID等于实际用户组ID(1000)。

      Linux中的每一个进程都关联有一个用户,也就是对应有一个UID ,如下面test进程,关联用户为“jiangzhaowei”,而jiangzhaowei对应的UID 为1000

    jiangzhaowei@kitking:~$ ps -aux
    USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
    jiangzh+ 10558  0.0  0.0   4508   744 pts/0    S+   08:41   0:00 ./test
    jiangzh+ 10562  0.0  0.0  38372  3584 pts/1    R+   08:41   0:00 ps -aux
    nobody   19758  0.0  0.1 401716  8452 ?        Sl   Oct14   0:07 Passenger ust-router
    daemon   19853  0.0  2.5 795640 197504 ?       Sl   Oct14   0:59 Passenger RubyApp: /opt/redmine.org.cn/apps/redmine/htdocs/
    

             进一步说明:

        由于每一个用户都对应有一个主用户组,以及若干个补充用户组,因此,每一个进程除了有一个对应的UID之外,还对应有一个主GID,以及若干个Supplementary GIDs。这些EUID和EGID就决定了一个进程所能访问的文件或者所能调用的系统API。例如,在下图中,PID为340的进程一般来说,就只能访问所有者为u0_a19的文件。

        

             一个进程的UID是怎么来的呢?在默认情况下,就等于创建它的进程的UID,也就是它的父进程的UID。Linux的第一个进程是init进程,它是由内核在启动完成后创建的,它的UID是root。然后系统中的所有其它进程都是直接由init进程或者间接由init进程的子进程来创建。所以默认情况下,系统的所有进程的UID都应该是root。但是实际情况并非如此,因为父进程在创建子进程之后,也就是在fork之后,可以调用setuid来改变它的UID。例如,在PC中,init进程启动之后,会先让用户登录。用户登录成功后,就对应有一个shell进程。该shell进程的UID就会被setuid修改为所登录的用户。之后系统中创建的其余进程的UID为所登录的用户。

            进程的UID除了来自于父进程之外,还有另外一种途径。上面我们说到,Linux的文件有三种权限,分别是Read、Wirte和Execute。其实还有另外一个种权限,叫做SUID。

            一个可执行文件一旦被设置了SUID位,那么当它被一个进程通过exec加载之后,该进程的EUID就会变成该可执行文件的所有者的UID。

            与SUID类似,文件还有另外一个称为SGID的权限,不过它描述的是用户组。也就是说,一个可执行文件一旦被设置了EGUID位,么当它被一个进程通过exec加载之后,该进程的主UID就会变成该可执行文件的所有者的主UID。

      接下来我使用“gitadmin”用户登录,运行test程序,如下:

    jiangzhaowei@kitking:~/share/test$ ll
    -rwxrwxr-x  1 jiangzhaowei jiangzhaowei 8520 Oct 18 08:40 test*
    
    //gitadmin运行test程序
    gitadmin@kitking:/home/jiangzhaowei/share/test$ id
    uid=1002(gitadmin) gid=1002(gitadmin) groups=1002(gitadmin)
    gitadmin@kitking:/home/jiangzhaowei/share/test$ ./test 
    uid=1002, gid=1002, euid=1002, egid=1002

      我们增加test的SUID/SGID属性,EUID/EGID已经改变为文件所有者的权限。

    jiangzhaowei@kitking:~/share/test$ ll
    -rwsrwsr-x  1 jiangzhaowei jiangzhaowei 8520 Oct 18 08:40 test*
    
    //同样gitadmin再运行test程序,程序已经有了用户jiangzhaowei所取得的所有权限
    gitadmin@kitking:/home/jiangzhaowei/share/test$ ./test 
    uid=1002, gid=1002, euid=1000, egid=1000
  • 相关阅读:
    Flash与JS之间相互调用以及参数传递
    在Javascript中监听flash事件(转)
    DataTables.js插入数据的两种方式
    DataTable在内存中的使用
    oracle分页存储过程
    清空highcharts数据
    JDBC源码分析(加载过程)
    MAVEN实现多环境搭建
    Maven基础
    Ajax如何提交数据到springMVC后台
  • 原文地址:https://www.cnblogs.com/jiangzhaowei/p/4062013.html
Copyright © 2020-2023  润新知