zoukankan      html  css  js  c++  java
  • 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_ISUID 04000 set user ID on execution  [1]
    S_ISGID 02000 set group ID on execution [2]
    S_ISVTX 01000 sticky bit                [3]
    S_IRUSR 00400 owner has read permission
    S_IWUSR 00200 owner has write permission
    S_IXUSR 00100 owner has execute permission
    S_IRGRP 00040 group has read permission
    S_IWGRP 00020 group has write permission
    S_IXGRP 00010 group has execute permission
    S_IROTH 00004 others have read permission
    S_IWOTH 00002 others have write permission
    S_IXOTH 00001 others 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>
    ", 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
    ",
     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
    ", filepath);
    108     (void) printf("Access: (%04o/%s)
    ", (int)(sb.st_mode & ~S_IFMT), s);
    109     (void) printf("  Type: %s
    ", 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
  • 相关阅读:
    [转自大神]js拖拽小总结
    双飞翼布局
    圣杯布局
    页面伸缩布局实例
    css动画
    html的简单笔记01
    沙扬娜拉一首——赠日本女郎(徐志摩)
    滑动门功能
    边框圆角练习--跳动的心
    边框圆角
  • 原文地址:https://www.cnblogs.com/idorax/p/6415385.html
Copyright © 2011-2022 走看看