我正在使用C++ ofstream写出一个文件.我想将权限设置为只能由用户访问:700.在unix中; 我想我可以发一个system("chmod 700 file.txt");但我需要这个代码才能在Windows上运行.我可以使用一些Windows API; 但是最好的c ++跨平台方法是什么?
Mik*_*ike 29
具有讽刺意味的是,我今天早些时候遇到了同样的需求.
就我而言,答案归结为我在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支持他们所谓的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
Run Code Online (Sandbox Code Playgroud)
重要的是要记住我的解决方案只提供DOS类型的安全性.这也称为无安全性,但它是大多数应用程序在Windows上提供的安全性.
此外,根据我的解决方案,如果您没有定义STRICT_UGO_PERMISSIONS,当您授予组或其他人的权限(或删除它)时,您实际上是在更改所有者.如果您不想这样做,但仍然不需要完整的Windows ACL权限,只需定义STRICT_UGO_PERMISSIONS即可.
没有跨平台的方法来做到这一点.Windows不支持Unix风格的文件权限.为了做你想做的事,你将不得不考虑为该文件创建一个访问控制列表,这将允许你明确定义用户和组的访问权限.
另一种方法是在目录中创建文件,该目录的安全设置已设置为排除除用户之外的所有人.
使用 C++17 及其std::filesystem.
#include <exception>
//#include <filesystem>
#include <experimental/filesystem> // Use this for most compilers as of yet.
//namespace fs = std::filesystem;
namespace fs = std::experimental::filesystem; // Use this for most compilers as of yet.
int main()
{
fs::path myFile = "path/to/file.ext";
try {
fs::permissions(myFile, fs::perms::owner_all); // Uses fs::perm_options::replace.
}
catch (std::exception& e) {
// Handle exception or use another overload of fs::permissions()
// with std::error_code.
}
}
Run Code Online (Sandbox Code Playgroud)
参见std::filesystem::permissions、std::filesystem::perms和std::filesystem::perm_options。
| 归档时间: |
|
| 查看次数: |
45345 次 |
| 最近记录: |