我正在使用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,还要学习安全描述符,访问令牌和许多其他高级Windows安全概念.
幸运的是,对于我目前的需求,我不需要访问控制模型提供的真正安全性.我可以基本上假装在Windows上设置权限,只要我真的在Linux上设置权限.
Windows支持他们所谓的chmod(2)的"符合ISO C++标准"版本.这个API被称为_chmod,它类似于chmod(2),但更有限,而不是类型或名称兼容(当然).Windows也有一个不推荐使用的chmod,所以你不能简单地将chmod添加到Windows并在Linux上使用直接的chmod(2).
我写了以下内容:
#include#include #ifdef _WIN32 # include 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即可.
没有跨平台的方法来做到这一点.Windows不支持Unix风格的文件权限.为了做你想做的事,你将不得不考虑为该文件创建一个访问控制列表,这将允许你明确定义用户和组的访问权限.
另一种方法是在目录中创建文件,该目录的安全设置已设置为排除除用户之外的所有人.