您的位置:首页 > 运维架构 > Linux

Linux 文件访问权限详解

2012-03-05 09:09 190 查看
一直以root登陆使用linux的人来说很少有权限被拒这种概念,但某些时候又深受权限拒绝困扰。

知道为什么很多程序中需要使用getuid(),setuid()?为什么以普通权限登陆的用户不能进入/root,为什么在/目录下执行ls -l后可以显示root的信息,但ls /root -al却是权限不够?为什么有些文件夹可以继续创建文件,但就是不能ls?等等,相信看了此文就能明白。

主要是学习笔记,不足之处请指正。

[root@xxx/]# lsb_release -a
LSB Version:    :core-3.1-ia32:core-3.1-noarch:graphics-3.1-ia32:graphics-3.1-noarch
Distributor ID: CentOS
Description:    CentOS release 5.4 (Final)
Release:        5.4
Codename:       Final


一、口令文件

1,格式

存储文件/etc/passwd,格式如下:

root:x:0:0:root:/root:/bin/bash
  aaa:x:501:501:bj, bj, 8111111,136000111:/home/aaa:/bin/bash
用户名:加密密码:用户ID:组ID:注释:工作目录:shell:

默认情况是第一行的格式;注释字段可以自行修改,用逗号隔开,如第二行格式,这主要是给finger命令使用时可解析。

可以vi /etc/passwd修改,但为了保证其格式的正确性,请用vipw命令编译此文件。

sh-3.2# finger aaa
  Login: aaa                              Name: bj
  Directory: /home/aaa                    Shell: /bin/bash
  Office:  bj,  8111111                   Home Phone: 136000111
  Never logged in.
  No mail.
  No Plan.


2,编程实例



/*getpwnam_pwuid.c*/
  #include <pwd.h>
  #include <stdlib.h>
  #include <stdio.h>
 
  int main(void)
  {
      //struct passwd *pwd = getpwnam("aaa");
      struct passwd *pwd = getpwuid(501);
      if(pwd == NULL)
      {
          printf("err.\n");
          return 1;
      }
 
      printf("name:%s\n", pwd->pw_name);
      printf("passwd:%s\n", pwd->pw_passwd);
      printf("description:%s\n", pwd->pw_gecos);
      printf("uid:%d\n", pwd->pw_uid);
      printf("gid:%d\n", pwd->pw_gid);
      printf("dir:%s\n", pwd->pw_dir);
      printf("shell:%s\n", pwd->pw_shell);
 
      return 0;
  }


sh-3.2# gcc getpwnam_pwuid.c -o app
  sh-3.2# ./app
  name:aaa
  passwd:x
  description:bj, bj, 8111111,136000111
  uid:501
  gid:501
  dir:/home/aaa
  shell:/bin/bash


二、组文件

1,格式

存储文件/etc/group,格式如下

root:x:0:root
  bin:x:1:root,bin,daemon
  aaa:x:501:


组名:加密密码:组ID:指向的各用户名

2,改变文件uid和gid.

sh-3.2# pwd
    /root/study
  sh-3.2# ls -al
    -rw-r--r--  1 root root      397 10-11 03:23 test.c


chgrp 改变所属组ID,当然只有root权限才可以修改。



sh-3.2# chgrp aaa test.c
  sh-3.2# ls -al
    -rw-r--r--  1 root aaa       397 10-11 03:23 test.c


这个aaa就是新组名,其在/etc/group中,可以通过adduser aaa自行添加

sh-3.2# cat /etc/group
    root:x:0:root
    bin:x:1:root,bin,daemon
    daemon:x:2:root,bin,daemon
    .
    .
    .
    gdm:x:42:
    sabayon:x:86:
    plmtest:x:500:
    aaa:x:501:


chown 改变用户ID或组ID

sh-3.2# chown aaa:aaa test.c
  sh-3.2# ls -al
    -rw-r--r--  1 aaa  aaa       397 10-11 03:23 test.c


3,编程实例

/*getgrnam.c*/
  #include <grp.h>
  #include <stdio.h>
 
  int main(int argc, char *argv[])
  {
      if(argv[1] == NULL)
      {
          printf("input error.\n");
          return 1;
      }
 
      struct group *gp = getgrnam(argv[1]);
      if(gp == NULL)
      {
          printf("err.\n");
          return 1;
      }
 
      printf("name:%s\n", gp->gr_name);
      printf("psswd:%s\n", gp->gr_passwd);
      printf("gid:%d\n", gp->gr_gid);
 
      int i;
      for(i = 0; gp->gr_mem[i] != NULL; i++)
      {
          printf("group name:%s\n", gp->gr_mem[i]);
      }
 
 
      return 0;
  }
sh-3.2# gcc getgrnam.c -o app
  sh-3.2# ./app bin
  name:bin
  psswd:x
  gid:1
  group name:root
  group name:bin
  group name:daemon


4,文件权限

不细讲了

sh-3.2# ls -al
  总计 483984
  drwxr-x--- 13 root  root       4096 02-22 00:01 .
  drwxr-xr-x 32 root  root       4096 02-21 21:15 ..
  -rw-r--r--  1 root  root  464023491 10-25 22:33 3.3.005-080425.tgz
  -rw-------  1 root  root       9346 02-21 23:16 .bash_history
  -rw-r--r--  1 root  root         24 2007-01-06 .bash_logout
  -rw-r--r--  1 root  root        191 2007-01-06 .bash_profile
  -rw-r--r--  1 root  root        176 2007-01-06 .bashrc
  drwxrwxrwx 10  1000 users      4096 08-23 20:16 cflow-1.3
  -rw-r--r--  1 root  root     759691 08-23 20:13 cflow.tar.gz
  -rw-r--r--  1 root  root        100 2007-01-06 .cshrc
  -rwxr-xr-x  1 root  root        582 11-11 21:48 delete_M.sh
  -rw-r--r--  1 root  root       2518 11-11 20:25 .dir_colors


主要是最左边一列:drwxr-x---

10个字符,最左边是文件类型,-默认为普通文件;d:目录文件;l符号链接……

后面9个,3个一组共三组,分别表示所属用户uid的权限;所属组或者附属组gid的权限;其它权限。

三个字符分别是读、写、执行权限

读4,写2, 执行1

所以chmod 777 test.c,提升到读、写、执行权限。

5,组权限操作实例

此节演示相同组的成员之间共享资源,即不同uid但相同gid的用户共享同一组的资源。



为了方便起见,我同时开了两个终端。

"sh-3.2#"以root权限登陆的shell /bin/sh
  "[testa@xxx root]"以testa用户登陆的shell


注:下文提到的“用户”是指/etc/passwd里定义的通过终端登陆的用户(此文即以下增加的三个账号名)。

sh-3.2# useradd testa
  sh-3.2# useradd testb
  sh-3.2# useradd testc

  sh-3.2# tail -f /etc/passwd -n 4
  sabayon:x:86:86:Sabayon user:/home/sabayon:/sbin/nologin
  testa:x:500:500::/home/testa:/bin/bash
  testb:x:501:501::/home/testb:/bin/bash
  testc:x:502:502::/home/testc:/bin/bash


再开一个终端登陆testa,之前那个终端保持。

sh-3.2# su testa
  [testa@xxx root]$ id
  uid=500(testa) gid=500(testa) groups=500(testa)
  [testa@xxx home]$ ls -al
  总计 28
  drwxr-xr-x  5 root  root  4096 02-21 22:52 .
  drwxr-xr-x 32 root  root  4096 02-21 21:15 ..
  drwx------  3 testa testa 4096 02-21 22:56 testa
  drwx------  3 testb testb 4096 02-21 22:48 testb
  drwx------  3 testc testc 4096 02-21 22:52 testc

  [testa@xxx home]$ cd testb
  bash: cd: testb: 权限不够




通过root修改testb目录权限为770,即当前uid或者gid相同的用户均有读写执行权限。

sh-3.2# cd /home/
  sh-3.2# chmod 770 testb

  [testa@xxx home]$ ls -al
  总计 28
  drwxr-xr-x  5 root  root  4096 02-21 22:52 .
  drwxr-xr-x 32 root  root  4096 02-21 21:15 ..
  drwx------  3 testa testa 4096 02-21 22:56 testa
  drwxrwx---  3 testb testb 4096 02-21 22:48 testb   (here modify)
  drwx------  3 testc testc 4096 02-21 22:52 testc
 
  [testa@xxx home]$ cd testb
  bash: cd: testb: 权限不够
  [testa@xxx root]$ id


uid=500(testa) gid=500(testa) groups=500(testa)

此时虽然开放了testb的所属组权限,但用户testa的gid=500(testa) groups=500(testa),它还不属于testb组。

下面修改testa的gid为testb(或者增加其附属组groups值为testb)

sh-3.2# usermod -G testb testa  (增加用户testa的附属组testb)
  sh-3.2# id testa
  uid=500(testa) gid=500(testa) groups=500(testa),501(testb)
 
  此时testa终端需要重新登下,使刚才更改生效
  [testa@xxx root]$ exit
  exit
  [root@xxx ~]# su testa
  [testa@xxx root]$ id
  uid=500(testa) gid=500(testa) groups=500(testa),501(testb)
  [testa@xxx root]$ cd /home/
  [testa@xxx home]$ ls -al
  总计 28
  drwxr-xr-x  5 root  root  4096 02-21 22:52 .
  drwxr-xr-x 32 root  root  4096 02-21 21:15 ..
  drwx------  3 testa testa 4096 02-21 22:56 testa
  drwxrwx---  3 testb testb 4096 02-21 22:48 testb
  drwx------  3 testc testc 4096 02-21 22:52 testc
  [testa@xxx home]$ cd testb
  [testa@xxx testb]$ pwd
  /home/testb


以上是增加了用户testa的附属组testb,使其对于属于testb组的资源有了访问权限。

下面再使用newgrp切换用户testa的gid.

[testa@xxx testb]$ id
  uid=500(testa) gid=500(testa) groups=500(testa),501(testb)
  [testa@xxx testb]$ newgrp testb
  [testa@xxx testb]$ id
  uid=500(testa) gid=501(testb) groups=500(testa),501(testb)
 
  此时testa用户的gid已改为501(testb).


组之间的关系在文件/etc/group

sh-3.2# tail -f /etc/group -n 4      
  sabayon:x:86:
  testa:x:500:
  testb:x:501:testa (最后一列:组内用户列表。即组testb里包含testa,testa属于testb组,大概就这意思吧...)
  testc:x:502:




虽然知道控制组关系的文件,但不能直接修改些文件,否则执行newgrp时会出现"抱歉"错误提示.

当然root用户权限是无限制的,它访问文件时不需要进行权限检查。

三、相关系统调用

getuid();
  getgid();
  int setuid(uid_t uid);
  int setgid(gid_t gid);


只有超级用户或者需要设置的uid和当前用户的uid一致才可以设置,否则返回-1,置errno = EPERM, errno可以通过strerror()翻译。

其它:

[testa@xxx home]$ su testa
[testa@xxx home]$ sudo touch aa

testa is not in the sudoers file.  This incident will be reported.
以root权限vim /etc/sudoers
增加testa ALL=(ALL)   ALL


参考:APUE2E,1.8, 4.4, 8.11
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: