Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I need to know how to check the effective file access permissions for a given user, but it takes long to do this manually starting from / up to the target file or directory, checking group, ...etc.

share|improve this question

2 Answers 2

up vote 1 down vote accepted

From what I see, the only ways would be to either do what you describe, check each of the permissions sets against the effective user/group. Or you could try to set up sudo to be able to take test(1).

sudo -u luser test -x ~juser/bin/myprogram

Like you said, check the effective user/groups permissions:

:

# called as $0 usertocheck pathname {r|w|x}
# for example, permcheck luser ~juser/bin/myprogrm x
# displays either "root", "user", "groups", "other" or "none"
user=$1
file=$2
smode=$3
# if user has no access from state, an empty string is returned, fuid,
# fgid and fmode would become empty strings as well; the end result is
# always showing 'none' even if $user has access (except $user == 'root')
set -- $(stat -L -c '%u %g %a' $file 2>&-)
awk -f $tmpawk \
    -veuid="$(id -u $user)" \
    -vgrp="$(id -G $user)" \
    -vfuid="$1" \
    -vfgid="$2" \
    -vfmode="$(echo ibase=8\;$3 | bc)" \
    -vsmode="$smode" \
'BEGIN {
  if (euid == 0) { print "root"; exit; }
  split(grp,Groups);
  omode = fmode % 8; gmode = int(fmode / 8 % 8);
  umode = int(fmode / 64 % 8);
  # set up tests
  # these could be function, but not all version of awk has a function
  # statement
  if (smode == "r") {
    utest = int(umode / 4);
    gtest = int(gmode / 4);
    otest = int(omode / 4);
  }
  if (smode == "w") {
    utest = int(umode / 2 % 2);
    gtest = int(gmode / 2 % 2);
    otest = int(omode / 2 % 2);
  }
  if (smode == "x") {
    utest = (int(umode >= 4) && umode % 2);
    gtest = (int(gmode >= 4) && gmode % 2);
    otest = (int(omode >= 4) && omode % 2);
  }
  if (utest && fuid == euid) { print "user"; exit; }
  for (idx in Groups) {
    if (gtest && Groups[idx] == fgid) { print "group"; exit; }
  }
  if (otest) { print "other"; exit; }
  print "none";
}
'

On my Ubuntu 11.04 system, running this script takes about 16ms, on average. Also, stat does not need read/execute per

share|improve this answer

Would the stat command do the tick?

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.