具有讽刺意味的是,我今天早些时候刚刚遇到了同样的需求。
就我而言,答案取决于我在 Windows 上与 Linux 上需要什么级别的权限粒度。就我而言,我只关心 Linux 上的用户、组和其他权限。在 Windows 上,DOS 留下的基本读/写全部权限对我来说已经足够了,即我不需要在 Windows 上处理 ACL。
一般来说,Windows有两种权限模型:基本的DOS模型和较新的访问控制模型。在DOS模型下有一种权限:写权限。所有文件都可以读取,因此无法关闭读取权限(因为它不存在)。也没有执行权限的概念。如果一个文件可以被读取(答案是肯定的)并且它是二进制的,那么它就可以被执行;否则不能。
基本的 DOS 模型足以满足大多数 Windows 环境,即系统由单个用户在可以被认为相对安全的物理位置使用的环境。访问控制模型要复杂几个数量级。
访问控制模型使用访问控制列表(ACL)来授予权限。权限只能由具有必要权限的进程授予。此模型不仅允许控制用户、组和其他具有读、写和执行权限的用户,而且还允许通过网络和 Windows 域之间控制文件。 (您也可以在使用 PAM 的 Unix 系统上获得这种程度的疯狂。)
注意:访问控制模型仅适用于 NTFS 分区,如果您使用 FAT 分区,则您是 SOL。
使用 ACL 是一件很痛苦的事情。这不是一项简单的任务,它不仅需要您学习 ACL,还需要学习所有有关安全描述符、访问令牌以及许多其他高级 Windows 安全概念的知识。
对我来说幸运的是,对于我当前的需求,我不需要访问控制模型提供的真正的安全性。我基本上可以在 Windows 上假装设置权限,只要我真的在 Linux 上设置权限即可。
Windows 支持他们所谓的“ISO C++ 一致”版本的 chmod(2)。这个 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。