Do I have permission?

10

The Challenge

Given a string indicating the symbolic notation of UNIX permission of a file and its ownership (user ID and group ID), decide whether a given user A has permission to read / write / execute it.

Related.

Permissions in UNIX system

In UNIX, every file has three classes of permissions (user, group and others) and ownership, including which user and which group it belongs to.

The symbolic notation consists of ten characters. The first character is not important in this challenge. The remaining nine characters are in three sets of three characters, representing permissions of user, group and others class. Characters in each set indicates whether reading / writing / executing is permitted. If permitted, it will be r, w or x. Otherwise, it will be -.

Note that setuid, setgid and sticky bit may change the third character of each set to s, S, t or T. Here's a simple rule: if the character is lowercase letter, then the permission is set; otherwise, it is not.

(For the details of symbolic notation of permissions, please refer to here.)

Every user has its user ID, and every group has its group ID. All IDs will be non-negative integers. A user will belong to at least one group. If a user A want to get access to a file, the system will check their permissions as follows:

  • If the file belongs to user A, check the permissions of user class.

  • If the file doesn't belong to A, but A belongs to the group which the file belongs to, check the permissions of group class.

  • Otherwise, check the permissions of others class.

However, there is one exception: if the user ID is 0 (superuser), they have permission to do anything!

Specifications

  • Your program / function should take these as input in any reasonable format:
    • Permissions in symbolic notation.
    • User ID and group ID which the file belongs to.
    • The user ID of A, and a list of group IDs which A belongs to.
    • Type of access. You can use any three different one-digit or one-character values for read, write and execute.
  • Return / output a truthy value if A has permission to access the file, or a falsy value if not.
  • You can assume that the first character of the notation will always be - (regular file).
  • This is , so the shortest in bytes wins!

Test Cases

The format here is [permissions, user ID of file, group ID of file, user ID of A, group IDs of A, type(r/w/x)].

[-rwx------, 13, 15, 13, [15, 24], r]: True   # user
[-rwxr-xr-x, 13, 24, 24, [15, 24], w]: False  # group 
[-rwxr-Sr-T, 13, 15, 24, [15, 35], x]: False  # group
[-rwsr-xr-t, 13, 15, 24, [24, 35], x]: True   # others
[----------, 13, 15, 0, [0, 1, 2], r]: True   # superuser
[----------, 13, 15, 1, [0, 1, 2], r]: False  # others
[----rwxrwx, 13, 15, 13, [15, 24], r]: False  # user

Colera Su

Posted 2017-11-29T07:02:39.563

Reputation: 2 291

Answers

6

JavaScript (ES6), 61 51 50 bytes

Takes 6 distinct parameters as input, in the order described in the challenge. Expects the last parameter to be 1 for read, 2 for write or 3 for execute. Returns 0 or 1.

(p,u,g,a,G,P)=>!a|p[u-a?6-3*G.includes(g)+P:P]>'Z'

Test cases

let f =

(p,u,g,a,G,P)=>!a|p[u-a?6-3*G.includes(g)+P:P]>'Z'

//            p             u   g   a   G          P
console.log(f('-rwx------', 13, 15, 13, [15, 24],  1)) // True  (user)
console.log(f('-rwxr-xr-x', 13, 24, 24, [15, 24],  2)) // False (group)
console.log(f('-rwxr-Sr-T', 13, 15, 24, [15, 35],  3)) // False (group)
console.log(f('-rwsr-xr-t', 13, 15, 24, [24, 35],  3)) // True  (others)
console.log(f('----------', 13, 15,  0, [0, 1, 2], 1)) // True  (superuser)
console.log(f('----------', 13, 15,  1, [0, 1, 2], 1)) // False (others)
console.log(f('----rwxrwx', 13, 15, 13, [15, 24],  1)) // False (user)

Arnauld

Posted 2017-11-29T07:02:39.563

Reputation: 111 334

2

Python 2, 76 70 67 63 59 58 56 55 52 49 48 bytes

lambda p,u,g,A,G,t:A*'_'<p[~(u==A)*3*(g in G)-t]

Try it online!

Takes type as 3 for read, 2 for write ,and 1 for execute

TFeld

Posted 2017-11-29T07:02:39.563

Reputation: 19 246

68 bytes – Mr. Xcoder – 2017-11-29T11:12:17.620

1It is not necessary to be superuser to have group ID 0. I added it to the test cases. – Colera Su – 2017-11-29T11:28:28.400

@ColeraSu Ah i misread, can the user id be negative? – TFeld – 2017-11-29T11:35:40.047

Both UID and GID will be non-negative. – Colera Su – 2017-11-29T11:38:38.220

1

Java (OpenJDK 8), 60 bytes

(p,u,g,U,G,t)->U<1|p.charAt(t+(u==U?0:G.contains(g)?3:6))>90

Try it online!

The mapping for the type is the following: 1 means r, 2 means w and 3 means x.

Olivier Grégoire

Posted 2017-11-29T07:02:39.563

Reputation: 10 647

1

Pyth, 22 21 bytes

|!Q}@@c3tw*nEQ-2}EEEG

Try it online. Test suite.

Takes input as six lines:

user id
permissions
file user id
file group
user groups
permission (0 = read, 1 = write, 2 = execute)

Explanation

|!Q}@@c3tw*nEQ-2}EEEG     Implicit: read user id to Q
 !Q                       True if user id is 0, false otherwise
|                         If true, just return it
         w                Read permission string
        -                 Omit first -
      c3                  Split in 3 parts
            E             Read file user id
           n Q            See if it doesn't equal Q
                          -> False (0) if user matches, true (1) otherwise
                 E        Read file group
                  E       Read user groups
                }         -> True (1) if group matches, false (0) otherwise
              -2          Subtract from 2
                          -> 1 if group matches, 2 otherwise
          *               Multiply the two numbers
                          -> 0 if user matches, 1 if group matches, 2 otherwise
     @                    Take correct part of permission string
    @                     Take correct character of that part
   }                G     See if it is in lowercase alphabet

PurkkaKoodari

Posted 2017-11-29T07:02:39.563

Reputation: 16 699