如何创建与现有目录具有相同访问权限的目录?

d0m*_*n1c 2 c unix stat

我需要创建一个与另一个文件夹具有相同权限的新文件夹.我的最终目标是完全复制目录及其内容.这是我的第一步,我似乎无法让它工作.

我的内容如下:

struct stat srcstat;
int srcstatus = stat(source, &srcstat);
if (chdir(dest))
    if (mkdir(dest, srcstat.st_mode)){
        printf("error: could not create <dest>\n");
        exit(1);
    }
Run Code Online (Sandbox Code Playgroud)

source是一个cstring,其中包含我想要使用其权限的文​​件夹的路径.dest是带有新文件夹路径的ac字符串.

具有旧文件夹和新文件夹权限的ls如下所示

drwxrwxrwx 2 kingacev CS-Majors 4096 Apr 18 17:03 test
drwxr-xr-x 2 kingacev CS-Majors 4096 Apr 18 18:12 test3
Run Code Online (Sandbox Code Playgroud)

我的第一个想法是我不能以我正在尝试的方式使用srcstat.st_mode.如果是这样的话,是否有同样简单的方法来做我想做的事情?如果没有,我离这个标记有多远?

zwo*_*wol 11

您正在违反" umask ",这是一个按进程设置,可以屏蔽文件和目录创建操作中的权限位.

没有安全的方法来禁用umask.你应该做的是创建模式为零的目录(即所有访问被拒绝),然后使用chmod(系统调用,而不是同名的shell命令)来调整你想要的权限.

您的程序片段还有许多其他错误.这很难做到,如果你弄错了,很可能是一个安全漏洞,所以我会详细写出正确的代码:

int
make_directory_like(const char *to_create,
                    const char *prototype)        
{
    struct stat st;
    if (lstat(prototype, &st)) {
        fprintf(stderr, "lstat: %s: %s\n", prototype, strerror(errno));
        return -1;
    }
    if (!S_ISDIR(st.st_mode)) {
        fprintf(stderr, "lstat: %s: %s\n", prototype, strerror(ENOTDIR));
        return -1;
    }
    /* create directory initially with no perms at all - this is the only
       safe way to suppress the effects of the umask.  */
    if (mkdir(to_create, 0000)) {
        if (errno != EEXIST) {
            fprintf(stderr, "mkdir: %s: %s\n", to_create, strerror(errno));
            return -1;
        } else {
            /* check whether the thing that exists is a directory */
            struct stat st2;
            if (lstat(to_create, &st2)) {
                fprintf(stderr, "lstat: %s: %s\n", to_create, strerror(errno));
                return -1;
            }
            if (!S_ISDIR(st2.st_mode)) {
                fprintf(stderr, "mkdir: %s: %s\n", to_create, strerror(EEXIST));
                return -1;
            }
        }
    }
    if (chmod(to_create, st.st_mode & ~S_IFMT)) {
        fprintf(stderr, "chmod: %s: %s\n", to_create, strerror(errno));
        return -1;
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

练习:

  1. 为什么这是抑制umask效果的唯一安全方法?(提示:线程.但这只是其中一个原因.)
  2. 我为什么要使用lstat而不是stat
  3. 如果失败,为什么有必要统计创建路径?mkdirerrno == EEXIST
  4. 为什么你正在使用它是不正确的chdir?(有两个原因.)
  5. 当我们不知道那里是否存在某些东西时,为什么继续使用to-create路径是安全的mkdir
  6. 为什么这& ~S_IFMT件事是必要的?

  • 这里不使用`chdir`的最重要原因是使用它来检查目录是否存在引入[TOCTOU竞赛](https://cwe.mitre.org/data/definitions/367.html).第二个最重要的原因是,将cwd恢复到以前的状态可能是**不可能*(例如,如果程序是在父级否认搜索权限的目录内启动的话 - 这种情况很少见,但并非闻所未闻) .第三个最重要的原因是cwd是进程状态,而不是线程状态,因此在多线程程序中,更改工作目录会干扰其他线程. (3认同)