Chinaunix首页 | 论坛 | 博客
  • 博客访问: 75896
  • 博文数量: 13
  • 博客积分: 229
  • 博客等级: 二等列兵
  • 技术积分: 162
  • 用 户 组: 普通用户
  • 注册时间: 2011-04-03 09:45
文章分类

全部博文(13)

文章存档

2013年(2)

2012年(11)

分类: LINUX

2012-03-11 13:51:01

    一直以root登陆使用linux的人来说很少有权限被拒这种概念,但某些时候又深受权限拒绝困扰。
知道为什么很多程序中需要使用getuid(),setuid()?为什么以普通权限登陆的用户不能进入/root,为什么在/目录下执行ls -l后可以显示root的信息,但ls /root -al却是权限不够?为什么有些文件夹可以继续创建文件,但就是不能ls?等等,相信看了此文就能明白。
主要是学习笔记,不足之处请指正。
 

点击(此处)折叠或打开

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


一、口令文件
1,格式
  存储文件/etc/passwd,格式如下:

点击(此处)折叠或打开

  1. root:x:0:0:root:/root:/bin/bash
  2. aaa:x:501:501:bj, bj, 8111111,136000111:/home/aaa:/bin/bash


用户名:加密密码:用户ID:组ID:注释:工作目录:shell:

  默认情况是第一行的格式;注释字段可以自行修改,用逗号隔开,如第二行格式,这主要是给finger命令使用时可解析。
  可以vi /etc/passwd修改,但为了保证其格式的正确性,请用vipw命令编译此文件。

点击(此处)折叠或打开

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


2,编程实例

点击(此处)折叠或打开

  1. /*getpwnam_pwuid.c*/
  2.   #include <pwd.h>
  3.   #include <stdlib.h>
  4.   #include <stdio.h>
  5.    
  6.   int main(void)
  7.   {
  8.       //struct passwd *pwd = getpwnam("aaa");
  9.       struct passwd *pwd = getpwuid(501);
  10.       if(pwd == NULL)
  11.       {
  12.           printf("err.\n");
  13.           return 1;
  14.       }
  15.    
  16.       printf("name:%s\n", pwd->pw_name);
  17.       printf("passwd:%s\n", pwd->pw_passwd);
  18.       printf("description:%s\n", pwd->pw_gecos);
  19.       printf("uid:%d\n", pwd->pw_uid);
  20.       printf("gid:%d\n", pwd->pw_gid);
  21.       printf("dir:%s\n", pwd->pw_dir);
  22.       printf("shell:%s\n", pwd->pw_shell);
  23.    
  24.       return 0;
  25.   }

点击(此处)折叠或打开

  1. sh-3.2# gcc getpwnam_pwuid.c -o app
  2. sh-3.2# ./app
  3. name:aaa
  4. passwd:x
  5. description:bj, bj, 8111111,136000111
  6. uid:501
  7. gid:501
  8. dir:/home/aaa
  9. shell:/bin/bash


二、组文件
1,格式
  存储文件/etc/group,格式如下

点击(此处)折叠或打开

  1. root:x:0:root
  2. bin:x:1:root,bin,daemon
  3. aaa:x:501:

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

2,改变文件uid和gid.


点击(此处)折叠或打开

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

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

点击(此处)折叠或打开

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

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

点击(此处)折叠或打开

  1. sh-3.2# cat /etc/group
  2. root:x:0:root
  3. bin:x:1:root,bin,daemon
  4. daemon:x:2:root,bin,daemon
  5. .
  6. .
  7. .
  8. gdm:x:42:
  9. sabayon:x:86:
  10. plmtest:x:500:
  11. aaa:x:501:

  chown 改变用户ID或组ID

点击(此处)折叠或打开

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

3,编程实例
 

点击(此处)折叠或打开

  1. /*getgrnam.c*/
  2. #include <grp.h>
  3. #include <stdio.h>
  4.   
  5. int main(int argc, char *argv[])
  6. {
  7.     if(argv[1] == NULL)
  8.     {
  9.         printf("input error.\n");
  10.         return 1;
  11.     }
  12.   
  13.     struct group *gp = getgrnam(argv[1]);
  14.     if(gp == NULL)
  15.     {
  16.         printf("err.\n");
  17.         return 1;
  18.     }
  19.   
  20.     printf("name:%s\n", gp->gr_name);
  21.     printf("psswd:%s\n", gp->gr_passwd);
  22.     printf("gid:%d\n", gp->gr_gid);
  23.   
  24.     int i;
  25.     for(i = 0; gp->gr_mem[i] != NULL; i++)
  26.     {
  27.         printf("group name:%s\n", gp->gr_mem[i]);
  28.     }
  29.   
  30.   
  31.     return 0;
  32. }

点击(此处)折叠或打开

  1. sh-3.2# gcc getgrnam.c -o app
  2. sh-3.2# ./app bin
  3. name:bin
  4. psswd:x
  5. gid:1
  6. group name:root
  7. group name:bin
  8. group name:daemon


4,文件权限
  不细讲了

点击(此处)折叠或打开

  1. sh-3.2# ls -al
  2. 总计 483984
  3. drwxr-x--- 13 root root 4096 02-22 00:01 .
  4. drwxr-xr-x 32 root root 4096 02-21 21:15 ..
  5. -rw-r--r-- 1 root root 464023491 10-25 22:33 3.3.005-080425.tgz
  6. -rw------- 1 root root 9346 02-21 23:16 .bash_history
  7. -rw-r--r-- 1 root root 24 2007-01-06 .bash_logout
  8. -rw-r--r-- 1 root root 191 2007-01-06 .bash_profile
  9. -rw-r--r-- 1 root root 176 2007-01-06 .bashrc
  10. drwxrwxrwx 10 1000 users 4096 08-23 20:16 cflow-1.3
  11. -rw-r--r-- 1 root root 759691 08-23 20:13 cflow.tar.gz
  12. -rw-r--r-- 1 root root 100 2007-01-06 .cshrc
  13. -rwxr-xr-x 1 root root 582 11-11 21:48 delete_M.sh
  14. -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的用户共享同一组的资源。
 
  为了方便起见,我同时开了两个终端。

点击(此处)折叠或打开

  1. "sh-3.2#"以root权限登陆的shell /bin/sh
  2. "[testa@xxx root]"以testa用户登陆的shell
注:下文提到的“用户”是指/etc/passwd里定义的通过终端登陆的用户(此文即以下增加的三个账号名)。

点击(此处)折叠或打开

  1. sh-3.2# useradd testa
  2. sh-3.2# useradd testb
  3. sh-3.2# useradd testc

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

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

点击(此处)折叠或打开

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

  11. [testa@xxx home]$ cd testb
  12. bash: cd: testb: 权限不够
 
  通过root修改testb目录权限为770,即当前uid或者gid相同的用户均有读写执行权限。
 

点击(此处)折叠或打开

  1. sh-3.2# cd /home/
  2. sh-3.2# chmod 770 testb

  3. [testa@xxx home]$ ls -al
  4. 总计 28
  5. drwxr-xr-x 5 root root 4096 02-21 22:52 .
  6. drwxr-xr-x 32 root root 4096 02-21 21:15 ..
  7. drwx------ 3 testa testa 4096 02-21 22:56 testa
  8. drwxrwx--- 3 testb testb 4096 02-21 22:48 testb (here modify)
  9. drwx------ 3 testc testc 4096 02-21 22:52 testc

  10. [testa@xxx home]$ cd testb
  11. bash: cd: testb: 权限不够
  12. [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)

 

点击(此处)折叠或打开

  1. sh-3.2# usermod -G testb testa (增加用户testa的附属组testb)
  2. sh-3.2# id testa
  3. uid=500(testa) gid=500(testa) groups=500(testa),501(testb)

  4. 此时testa终端需要重新登下,使刚才更改生效
  5. [testa@xxx root]$ exit
  6. exit
  7. [root@xxx ~]# su testa
  8. [testa@xxx root]$ id
  9. uid=500(testa) gid=500(testa) groups=500(testa),501(testb)
  10. [testa@xxx root]$ cd /home/
  11. [testa@xxx home]$ ls -al
  12. 总计 28
  13. drwxr-xr-x 5 root root 4096 02-21 22:52 .
  14. drwxr-xr-x 32 root root 4096 02-21 21:15 ..
  15. drwx------ 3 testa testa 4096 02-21 22:56 testa
  16. drwxrwx--- 3 testb testb 4096 02-21 22:48 testb
  17. drwx------ 3 testc testc 4096 02-21 22:52 testc
  18. [testa@xxx home]$ cd testb
  19. [testa@xxx testb]$ pwd
  20. /home/testb

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

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

点击(此处)折叠或打开

  1. [testa@xxx testb]$ id
  2. uid=500(testa) gid=500(testa) groups=500(testa),501(testb)
  3. [testa@xxx testb]$ newgrp testb
  4. [testa@xxx testb]$ id
  5. uid=500(testa) gid=501(testb) groups=500(testa),501(testb)

  6. 此时testa用户的gid已改为501(testb).


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

点击(此处)折叠或打开

  1. sh-3.2# tail -f /etc/group -n 4
  2. sabayon:x:86:
  3. testa:x:500:
  4. testb:x:501:testa (最后一列:组内用户列表。即组testb里包含testa,testa属于testb组,大概就这意思吧...)
  5. testc:x:502:
 
  虽然知道控制组关系的文件,但不能直接修改些文件,否则执行newgrp时会出现"抱歉"错误提示.
当然root用户权限是无限制的,它访问文件时不需要进行权限检查。


三、相关系统调用

点击(此处)折叠或打开

  1. getuid();
  2. getgid();
  3. int setuid(uid_t uid);
  4. int setgid(gid_t gid);

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


其它:

点击(此处)折叠或打开

  1. [testa@xxx home]$ su testa
  2. [testa@xxx home]$ sudo touch aa

  3. testa is not in the sudoers file. This incident will be reported.

点击(此处)折叠或打开

  1. 以root权限vim /etc/sudoers
  2. 增加testa ALL=(ALL) ALL


参考:APUE2E,1.8, 4.4, 8.11

  

阅读(1714) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~