4

我有一个/a/b用户可读的文件A。但/a不提供可执行权限A,因此路径/a/b无法遍历/a。对于任意长的路径,我将如何确定由于用户无法访问中间路径而无法访问给定路径的原因?

4

4 回答 4

5

手动解析树并将错误精确定位到单行的替代答案是使用 namei 工具。

namei -mo a/b/c/d
f: a/b/c/d
 drwxrw-rw- rasjani rasjani a
 drw-rwxr-x rasjani rasjani b
                        c - No such file or directory

这显示了整个树结构和权限,直到权限被拒绝的条目。

于 2016-05-19T07:52:30.400 回答
1

像这样的东西:

#!/bin/bash
PAR=${1}
PAR=${PAR:="."}
if ! [[ "${PAR:0:1}" == / || "${PAR:0:2}" == ~[/a-z] ]]
then
  TMP=`pwd`
  PAR=$(dirname ${TMP}/${PAR})
fi

cd $PAR 2> /dev/null
if [ $? -eq 1 ]; then
  while [ ! -z "$PAR" ]; do
    PREV=$(readlink -f ${PAR})
    TMP=$(echo ${PAR}|awk -F\/ '{$NF=""}'1|tr ' ' \/)
    PAR=${TMP%/}
    cd ${PAR} 2>/dev/null
    if [ $? -eq 0 ]; then
      if [ -e ${PREV} ]; then
        ls -ld ${PREV}
      fi
      exit
    fi
  done
fi

丑陋但它会完成工作..

所以这个想法基本上是采用参数 $1,如果它不是绝对目录,则将其扩展为这样,然后删除路径的最后一个元素并尝试 cd 进入它,如果它失败,rince 并重复.. 如果它有效, PREV 将保存用户无法 cd 进入的最后一个目录,因此将其打印出来..

于 2016-05-18T13:52:54.853 回答
1

这是我一起扔的。在写这篇文章之前,我实际上并没有看 rasjani 的答案,但它使用了相同的概念,即您获取命令的退出状态。基本上它遍历所有目录(从最远的链开始)并尝试ls它们。如果退出状态为 0,则ls成功,它会打印出它不能打印的最后一个目录ls(我不确定在某些边缘情况下会发生什么,比如你无法访问任何东西):

LAST=/a/b
while [ ! -z "$LAST" ] ; do
    NEXT=`echo "$LAST" | sed 's/[^\/]*$//' | sed 's/\/$//'`
    ls "$NEXT" 2> /dev/null > /dev/null
    if [ $? -eq 0 ] ; then 
        echo "Can't access: $LAST"
        break
    fi
    LAST="$NEXT"
done

我喜欢把这样的东西放在一行上,只是为了好玩:

LAST=/a/b; while [ ! -z "$LAST" ] ; do NEXT=`echo "$LAST" | sed 's/[^\/]*$//' | sed 's/\/$//'`; ls "$NEXT" 2> /dev/null > /dev/null; if [ $? -eq 0 ] ; then echo "Can't access: $LAST"; break; fi; LAST="$NEXT"; done
于 2016-05-24T15:48:35.253 回答
1

我有下面的 C 程序供您执行此操作。以下是步骤

  1. 将程序复制并保存为 file.c。
  2. 用 gcc file.c -o 文件编译程序
  3. 将其作为 ./file PATH 执行

假设您的路径为 /a/b/c/d 并且您没有“c”的权限,那么输出将是

  Given Path = /a/b/c/d

  No permission on = /a/b/c

为了获得许可,我依赖“EACCES”错误。路径长度假定为 1024。

如果您有任何问题,请分享。

  #include <stdio.h>
  #include <string.h>
  #include <errno.h>

  #define MAX_LEN 1024

  int main(int argc, char *argv[])
  {
    char path[MAX_LEN] = "/home/sudhansu/Test";
    int i = 0;
    char parse[MAX_LEN] = "";

    if(argc == 2)
    {
      strcpy(path, argv[1]);
      printf("\n\t\t Given Path = %s\n", path);
    }
    else
    {
      printf("\n\t\t Usage : ./file PATH\n\n");
      return 0;
    }

    if(path[strlen(path)-1] != '/')
      strcat(path, "/");

    path[strlen(path)] = '\0';

    while(path[i])
    {
      if(path[i] == '/')
      {
        strncpy(parse, path, i+1);
        if(chdir(parse) < 0)
        {
          if(errno == EACCES)
          {
            printf("\t\t No permission on = [%s]\n", parse);
            break;
          }
        }
      }

      parse[i] = path[i];
      i++;
    }

    printf("\n");
    return 0;
  }

问候, 苏丹苏

于 2016-05-24T18:19:11.620 回答