zoukankan      html  css  js  c++  java
  • 实际用户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
  • 相关阅读:
    1058 A+B in Hogwarts (20)
    1046 Shortest Distance (20)
    1061 Dating (20)
    1041 Be Unique (20)
    1015 Reversible Primes (20)(20 分)
    pat 1027 Colors in Mars (20)
    PAT 1008 Elevator (20)
    操作系统 死锁
    Ajax的get方式传值 避免& 与= 号
    让IE浏览器支持CSS3表现
  • 原文地址:https://www.cnblogs.com/jiangzhaowei/p/4062013.html
Copyright © 2011-2022 走看看