gpt4 book ai didi

c++ - 如何在 C++ 中设置文件权限(跨平台)?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:40:42 27 4
gpt4 key购买 nike

我正在使用 C++ ofstream 写出一个文件。我想将权限设置为只能由用户访问:700。在unix中;我想我可以只发出一个 system("chmod 700 file.txt"); 但我需要这段代码才能在 Windows 上工作。我可以使用一些 Windows api;但是最好的 C++ 跨平台方法是什么?

最佳答案

具有讽刺意味的是,我今天早些时候遇到了同样的需求。

就我而言,答案归结为我在 Windows 和 Linux 上需要何种级别的权限粒度。就我而言,我只关心 Linux 上的用户、组和其他权限。在 Windows 上,DOS 留下的基本读/写所有权限对我来说已经足够了,即我不需要在 Windows 上处理 ACL。

一般来说,Windows 有两种权限模型:基本的 DOS 模型和较新的访问控制模型。在 DOS 模式下有一种特权:写特权。所有文件都可以读取,所以没有办法关闭读取权限(因为它不存在)。也没有执行权限的概念。如果一个文件可以读取(答案是肯定的)并且它是二进制的,那么它就可以被执行;否则不能。

基本的 DOS 模型足以满足大多数 Windows 环境,即系统由单个用户在相对安全的物理位置使用的环境。访问控制模型复杂了几个数量级。

访问控制模型使用访问控制列表 (ACL) 来授予权限。权限只能由具有必要权限的进程授予。此模型不仅允许控制具有读、写和执行权限的用户、组和其他人,而且还允许通过网络和 Windows 域之间控制文件。 (您也可以在带有 PAM 的 Unix 系统上获得这种程度的疯狂。)

注意:访问控制模型仅适用于 NTFS 分区,如果您使用的是 FAT 分区,那么您就是 SOL。

使用 ACL 是一件很麻烦的事。这不是一项微不足道的任务,它不仅需要您学习 ACL,还需要学习所有关于安全描述符、访问 token 和大量其他高级 Windows 安全概念的知识。

对我来说幸运的是,对于我当前的需求,我不需要访问控制模型提供的真正安全性。只要我真的在 Linux 上设置权限,我基本上可以假装在 Windows 上设置权限。

Windows 支持他们所谓的 chmod(2) 的“符合 ISO C++ 标准”的版本。这个 API 称为 _chmod,它类似于 chmod(2),但更受限制并且不兼容类型或名称(当然)。 Windows 也有一个已弃用的 chmod,因此您不能简单地将 chmod 添加到 Windows 并在 Linux 上直接使用 chmod(2)。

我写了以下内容:

#include <sys/stat.h>
#include <sys/types.h>

#ifdef _WIN32
# include <io.h>

typedef int mode_t;

/// @Note If STRICT_UGO_PERMISSIONS is not defined, then setting Read for any
/// of User, Group, or Other will set Read for User and setting Write
/// will set Write for User. Otherwise, Read and Write for Group and
/// Other are ignored.
///
/// @Note For the POSIX modes that do not have a Windows equivalent, the modes
/// defined here use the POSIX values left shifted 16 bits.

static const mode_t S_ISUID = 0x08000000; ///< does nothing
static const mode_t S_ISGID = 0x04000000; ///< does nothing
static const mode_t S_ISVTX = 0x02000000; ///< does nothing
static const mode_t S_IRUSR = mode_t(_S_IREAD); ///< read by user
static const mode_t S_IWUSR = mode_t(_S_IWRITE); ///< write by user
static const mode_t S_IXUSR = 0x00400000; ///< does nothing
# ifndef STRICT_UGO_PERMISSIONS
static const mode_t S_IRGRP = mode_t(_S_IREAD); ///< read by *USER*
static const mode_t S_IWGRP = mode_t(_S_IWRITE); ///< write by *USER*
static const mode_t S_IXGRP = 0x00080000; ///< does nothing
static const mode_t S_IROTH = mode_t(_S_IREAD); ///< read by *USER*
static const mode_t S_IWOTH = mode_t(_S_IWRITE); ///< write by *USER*
static const mode_t S_IXOTH = 0x00010000; ///< does nothing
# else
static const mode_t S_IRGRP = 0x00200000; ///< does nothing
static const mode_t S_IWGRP = 0x00100000; ///< does nothing
static const mode_t S_IXGRP = 0x00080000; ///< does nothing
static const mode_t S_IROTH = 0x00040000; ///< does nothing
static const mode_t S_IWOTH = 0x00020000; ///< does nothing
static const mode_t S_IXOTH = 0x00010000; ///< does nothing
# endif
static const mode_t MS_MODE_MASK = 0x0000ffff; ///< low word

static inline int my_chmod(const char * path, mode_t mode)
{
int result = _chmod(path, (mode & MS_MODE_MASK));

if (result != 0)
{
result = errno;
}

return (result);
}
#else
static inline int my_chmod(const char * path, mode_t mode)
{
int result = chmod(path, mode);

if (result != 0)
{
result = errno;
}

return (result);
}
#endif

重要的是要记住我的解决方案只提供 DOS 类型的安全性。这也称为无安全性,但这是大多数应用程序在 Windows 上为您提供的安全性。

此外,根据我的解决方案,如果您没有定义 STRICT_UGO_PERMISSIONS,当您授予组或其他权限(或为此删除它)时,您实际上是在更改所有者。如果您不想这样做,但您仍然不需要完整的 Windows ACL 权限,只需定义 STRICT_UGO_PERMISSIONS。

关于c++ - 如何在 C++ 中设置文件权限(跨平台)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4778657/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com