Unix/Linux文件类型及访问权限

在Linux系统中,有7种文件类型。

  1. 普通文件 (regular file)
  2. 目录文件 (directory)
  3. 链接文件 (symbolic link)
  4. 管道文件 (FIFO)
  5. 套接字文件 (socket)
  6. 字符设备文件 (character device)
  7. 块设备文件    (block device)

在Solaris上,还有一种文件类型, 叫做door文件。

而一个文件的Unix访问权限,包括12位,通常用4个8进制位表示,

位标志八进制值含义
S_ISUID04000set user ID on execution  [1]
S_ISGID02000set group ID on execution [2]
S_ISVTX01000sticky bit                [3]
S_IRUSR00400owner has read permission
S_IWUSR00200owner has write permission
S_IXUSR00100owner has execute permission
S_IRGRP00040group has read permission
S_IWGRP00020group has write permission
S_IXGRP00010group has execute permission
S_IROTH00004others have read permission
S_IWOTH00002others have write permission
S_IXOTH00001others have execute permission

通常我们使用"chmod 777 <file>", 本质上是"chmod 0777 <file>"。

SUID, SGID, SVTX不常见,这里重点解释一下。

[1] SUID bit: Set User ID 位

When you execute a program that has the SUID bit enabled, you inherit the 
permissions of that program's owner. Programs that do not have the SUID bit 
set are run with the permissions of the user who started the program.

[2] SGID bit: Set Group ID位

The set-group-ID bit (S_ISGID) has several special uses.  For a directory it 
indicates that BSD semantics is to be used for that directory: files created
there inherit their group ID from the directory, not from the effective group ID
of the creating process, and directories created there will also get the S_ISGID
bit set. For a file that does not have the group execution bit (S_IXGRP) set,
the set-group-ID bit indicates mandatory file/record locking.

[3] SVTX bit: Sticky(粘滞)位

// From: https://en.wikipedia.org/wiki/Sticky_bit
When a directory's sticky bit is set, the filesystem treats the files in such directories in a special way so only the file's owner, the directory's owner, or root user can rename or delete the file. Without the sticky bit set, any user with write and execute permissions for the directory can rename or delete contained files, regardless of the file's owner. Typically this is set on the /tmp directory to prevent ordinary users from deleting or moving other users' files.

e.g. (目录/tmp的sticky位已经设置,虽然文件/tmp/dorax的权限是0777, 但是它不能被用户veli删除,因为其ower是用户fanw。)

1 $ id -un
2 veli
3 $ stat /tmp | egrep 'Access:.*Uid'
4 Access: (1777/drwxrwxrwt)  Uid: (    0/    root)   Gid: (    0/    root)
5 $ ls -l /tmp/dorax
6 -rwxrwxrwx 1 fanw fanw 4 Feb 19 22:11 /tmp/dorax
7 $ rm -f /tmp/dorax
8 rm: cannot remove ‘/tmp/dorax’: Operation not permitted

扩展阅读:

1. Unix File Permissions 

2. Unix - File Permission / Access Modes 

最后,给出一个文件类型及权限位识别的C代码实现。

  1 /*
  2  * foo.c - get Unix/Linux file type and its access,
  3  *         mostly simliar to what GNU stat does
  4  */
  5 
  6 #include <stdio.h>
  7 #include <string.h>
  8 #include <sys/types.h>
  9 #include <sys/stat.h>
 10 #include <unistd.h>
 11 #include <errno.h>
 12 
 13 int
 14 main(int argc, char *argv[])
 15 {
 16     char        *filepath = NULL;
 17     char        *filetype = NULL;
 18     char        s[] = "----------";
 19     int        rc;
 20     struct stat    sb;
 21 
 22     if (argc != 2) {
 23         (void) fprintf(stderr, "Usage %s <file>\n", argv[0]);
 24         return (-1);
 25     }
 26 
 27     filepath = argv[1];
 28 
 29     (void) memset(&sb, 0, sizeof (struct stat));
 30 
 31     errno = 0;
 32     /* NOTE: don't use stat() as we will get symbolic link file type */
 33     if ((rc = lstat(filepath, &sb)) != 0) {
 34         (void) fprintf(stderr, "%s: cannot stat `%s': %s\n",
 35             argv[0], filepath, strerror(errno));
 36         return (-1);
 37     }
 38 
 39     /* get file type */
 40     if (S_ISREG(sb.st_mode)) {
 41         s[0] = '-';
 42         filetype = "regular file";
 43     }
 44     if (S_ISDIR(sb.st_mode)) {
 45         s[0] = 'd';
 46         filetype = "directory";
 47     }
 48     if (S_ISCHR(sb.st_mode)) {
 49         s[0] = 'c';
 50         filetype = "character special file";
 51     }
 52     if (S_ISBLK(sb.st_mode)) {
 53         s[0] = 'b';
 54         filetype = "block special file";
 55     }
 56     if (S_ISFIFO(sb.st_mode)) {
 57         s[0] = 'p';
 58         filetype = "fifo";
 59     }
 60     if (S_ISLNK(sb.st_mode)) {
 61         s[0] = 'l';
 62         filetype = "symbolic link";
 63     }
 64     if (S_ISSOCK(sb.st_mode)) {
 65         s[0] = 's';
 66         filetype = "socket";
 67     }
 68 #ifdef __sunos
 69     if (S_ISDOOR(sb.st_mode)) {
 70         s[0] = 'D';
 71         filetype = "door";
 72     }
 73 #endif
 74 
 75     /* parse set UID, set-group-ID, sticky bit */
 76     if (sb.st_mode & S_ISUID)
 77         s[3] = 'S';
 78     if (sb.st_mode & S_ISGID)
 79         s[6] = 'S';
 80     if (sb.st_mode & S_ISVTX)
 81         s[9] = 'T';
 82 
 83     /* parse owner rwx bit */
 84     if (sb.st_mode & S_IRUSR)
 85         s[1] ='r';
 86     if (sb.st_mode & S_IWUSR)
 87         s[2] ='w';
 88     if (sb.st_mode & S_IXUSR)
 89         s[3] = (s[3] == 'S') ? 's' : 'x';
 90 
 91     /* parse group rwx bit */
 92     if (sb.st_mode & S_IRGRP)
 93         s[4] = 'r';
 94     if (sb.st_mode & S_IWGRP)
 95         s[5] = 'w';
 96     if (sb.st_mode & S_IXGRP)
 97         s[6] = (s[6] == 'S') ? 's' : 'x';
 98 
 99     /* parse others rwx bit */
100     if (sb.st_mode & S_IROTH)
101         s[7] = 'r';
102     if (sb.st_mode & S_IWOTH)
103         s[8] = 'w';
104     if (sb.st_mode & S_IXOTH)
105         s[9] = (s[9] == 'T') ? 't' : 'x';
106 
107     (void) printf("  File: %s\n", filepath);
108     (void) printf("Access: (%04o/%s)\n", (int)(sb.st_mode & ~S_IFMT), s);
109     (void) printf("  Type: %s\n", filetype);
110 
111     return (0);
112 }

o 在Linux上编译并测试

$ gcc -g -Wall -m32 -o foo foo.c

$ ./foo /usr/bin/passwd
  File: /usr/bin/passwd
Access: (4755/-rwsr-xr-x)
  Type: regular file

$ ./foo /var/tmp
  File: /var/tmp
Access: (1777/drwxrwxrwt)
  Type: directory

$ ./foo /bin/sh
  File: /bin/sh
Access: (0777/lrwxrwxrwx)
  Type: symbolic link

$ mkfifo /tmp/fifo
$ ./foo /tmp/fifo
  File: /tmp/fifo
Access: (0664/prw-rw-r--)
  Type: fifo

$ ./foo /dev/null
  File: /dev/null
Access: (0666/crw-rw-rw-)
  Type: character special file

$ ./foo /dev/sda
  File: /dev/sda
Access: (0660/brw-rw----)
  Type: block special file

$ ./foo /var/tmp/.sshmux 
  File: /var/tmp/.sshmux
Access: (0600/srw-------)
  Type: socket

o 在Solaris上编译并测试

$ gcc -D__sunos -g -Wall -m64 -o foo foo.c

$ ./foo /usr/bin/passwd
  File: /usr/bin/passwd
Access: (6555/-r-sr-sr-x)
  Type: regular file

$ ./foo /var/tmp
  File: /var/tmp
Access: (1777/drwxrwxrwt)
  Type: directory

$ ./foo /dev/null
  File: /dev/null
Access: (0777/lrwxrwxrwx)
  Type: symbolic link

$ mkfifo /tmp/fifo && ./foo /tmp/fifo
  File: /tmp/fifo
Access: (0644/prw-r--r--)
  Type: fifo

$ ./foo /var/tmp/.sshmux 
  File: /var/tmp/.sshmux
Access: (0600/srw-------)
  Type: socket

$ ./foo /devices/pseudo/mm@0:null
  File: /devices/pseudo/mm@0:null
Access: (0666/crw-rw-rw-)
  Type: character special file

$ ./foo /devices/pci@0,0/pci8086,3410@9/pci1000,9263@0/sd@1,0:wd
  File: /devices/pci@0,0/pci8086,3410@9/pci1000,9263@0/sd@1,0:wd
Access: (0640/brw-r-----)
  Type: block special file
              
$ ./foo /var/run/zonestat_door 
  File: /var/run/zonestat_door
Access: (0644/Drw-r--r--)
  Type: door

 

转载于:https://www.cnblogs.com/idorax/p/6415385.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值