简体   繁体   English

MSVC2015上的实验性C ++ 17文件系统:与权限不一致

[英]Experimental C++17 filesystem on MSVC2015: inconsistencies with permissions

I'm trying to use the experimental <filesystem> library that should become part of C++17 (See draft technical spec N4100 ) on MSVC2015 (update 1). 我正在尝试在MSVC2015 (更新1)上使用应该成为C ++ 17(参见技术规范草案N4100 )的实验性<filesystem>库。

I could manage to display full content of a directory recursively: 我可以设法以递归方式显示目录的完整内容:

    using namespace std::tr2::sys;
    ...
    path dir = canonical(".");
    for (auto& p : recursive_directory_iterator(dir)) {
        if (is_regular_file(p))                
            cout << file_size(p);               
        perms pe = p.status().permissions();  // get authorisations
        cout <<"\t"<< (pe & perms::owner_read ? "r" : "-") // <== error should be allowed
            << (pe & perms::owner_write ? "w" : "-");
        cout <<"\t" << p << endl;     
    }

Problems and questions: 问题和疑问:

  1. Bitwise & on the perms object: The compiler complains with a C2440 error about a missing conversion from perms to bool. perms对象上的Bitwise & :编译器抱怨C2440有关从perms到bool的转换丢失的错误 But this should be allowed according to specs. 但这应该根据规格允许。 Is this a bug or did I miss something ? 这是一个错误还是我错过了什么?

  2. I cirumvented the issue by converting pe an unsigned. 我通过转换pe无符号来解决这个问题。 There I noted that the value is always 0xffff , for every files, including a file where I have intentionally withdrawn writing authorisations. 在那里我注意到,对于每个文件,值都是0xffff ,包括我故意撤回编写授权的文件。 Will a constant dummy value be returned for permissions on windows systematically or did I forget something to get the valid permissions ? 是否系统地为Windows上的权限返回一个常量虚拟值,或者我忘记了获得有效权限的内容?

Update : What I said below about Windows' permissions is true, but for some reason even the FILE_ATTRIBUTE_READONLY bit doesn't appear to be working. 更新 :我在下面谈到的关于Windows权限的内容是正确的,但由于某种原因,即使FILE_ATTRIBUTE_READONLY位似乎也没有起作用。 I'll file a bug :) 我会提交一个bug :)

As a workaround for now you can do a status() on the resulting path record, eg 作为现在的解决方法,您可以对生成的路径记录执行status() ,例如

#include <filesystem>
#include <iostream>
using namespace std;
using namespace std::tr2::sys;

int main() {
    path dir = canonical(".");
    for (auto& p : recursive_directory_iterator(dir)) {
        if (is_regular_file(p))
            cout << file_size(p);
        file_status stat = status(p); // Workaround bug in MSVC++2015
        perms pe = stat.permissions();  // get authorizations
        cout <<"\t"<< ((pe & perms::owner_read) != perms::none ? "r" : "-")
            << ((pe & perms::owner_write) != perms::none ? "w" : "-");
        cout <<"\t" << p << endl;
    }
}

on my system produces: 在我的系统上产生:

PS C:\Users\bion\Desktop\test> ..\fs.exe
68494859        r-      C:\Users\bion\Desktop\test\read-only.mp3
93805063        rw      C:\Users\bion\Desktop\test\read-write.mp3
PS C:\Users\bion\Desktop\test>

Bitwise & on the perms object: The compiler complains with a C2440 error about a missing conversion from perms to bool. perwise对象上的Bitwise&:编译器抱怨C2440有关从perms到bool的转换丢失的错误。 But this should be allowed according to specs. 但这应该根据规格允许。 Is this a bug or did I miss something ? 这是一个错误还是我错过了什么?

Bitwise & is supported through an overloaded operator& and should work fine. Bitwise &通过重载operator&支持operator&并且应该正常工作。 There is no conversion to bool. 没有转换为bool。 If you want a conversion to bool, the right way to do that is to compare with a constant declared by that enum class , eg: 如果你想转换为bool,那么正确的方法是与该enum class声明的常量进行比较,例如:

if ((permsVar & perms::owner_read) != perms::none)

or with a direct-initialized instance of that enum class: 或者使用该枚举类的直接初始化实例:

if ((permsVar & perms::owner_read) != perms{})

[bitmask.types] only says: [bitmask.types]只说:

The value Y is set in the object X if the expression X & Y is nonzero. 如果表达式X和Y非零,则在对象X中设置值Y.

not that there is some conversion from the literal 0 you can use to compare with the enum class . 并不是你可以用来与enum class进行比较的文字0一些转换。

I cirumvented the issue by converting pe an unsigned. 我通过转换pe无符号来解决这个问题。 There I noted that the value is always 0xffff, for every files, including a file where I have intentionally withdrawn writing authorisations. 在那里我注意到,对于每个文件,值都是0xffff,包括我故意撤回编写授权的文件。 Will a constant dummy value be returned for permissions on windows systematically or did I forget something to get the valid permissions ? 是否系统地为Windows上的权限返回一个常量虚拟值,或者我忘记了获得有效权限的内容?

Windows' permissions model really has no analogue to the Unix permissions model -- security descriptors do have owner and group owner values, but there's no generally accepted convention to map between Windows DACLs (which can express much finer-grained permission constructs than Unix permissions) and Unix permissions. Windows的权限模型实际上与Unix权限模型没有相似之处 - 安全描述符确实具有所有者和组所有者值,但是在Windows DACL之间没有普遍接受的约定(它可以表达比Unix权限更精细的权限构造)和Unix权限。

As a result, at present we just look for the readonly attribute, or for one specific set of attributes, and if it isn't that we "punt" and say that the permissions are unknown. 因此,目前我们只查找readonly属性,或者查找一组特定的属性,如果不是我们“踢”并且说权限未知。 If you want to be portable, you need to do something with the unknown constant. 如果你想要便携,你需要做一些未知的常数。

        // FILE STATUS FUNCTIONS
_FS_DLL _File_type __CLRCALL_PURE_OR_CDECL _Stat(const TCHAR *_Fname, _Perms *_Pmode)
    {   // get file status
    WIN32_FILE_ATTRIBUTE_DATA _Data;

    if (TFUN(GetFileAttributesEx)(_Fname, GetFileExInfoStandard, &_Data))
        {   // get file type and return permissions
        // !!! Here's where we check
        if (_Pmode != 0)
            *_Pmode = _Data.dwFileAttributes & FILE_ATTRIBUTE_READONLY
                ? READONLY_PERMS : perms::all;
        return (_Map_mode(_Data.dwFileAttributes));
        }
    else
        {   // invalid, get error code
        // error mapping code omitted
        }
    }

What would you expect us to do with a security descriptor like: 你期望我们用安全描述符做什么,比如:

O:BAG:SYD:PAI(A;;WD;;;WD)(A;;FA;;;S-1-5-21-2127521184-1604012920-1887927527-9342113)(A;;0x4;;;BA)

which says: 其中说:

O:BA : The owner is BUILTIN\\ADMINISTRATORS . O:BA :所有者是BUILTIN\\ADMINISTRATORS
G:SY : The group owner is NT AUTHORITY\\LOCAL SYSTEM . G:SY :集团所有者是NT AUTHORITY\\LOCAL SYSTEM Note that the group is not generally used at all in Windows permissions and exists only for compatibility with Interix, in which case Interix is the only one reading or writing the security descriptor and as such can do whatever it wants. 请注意,该组通常不会在Windows权限中使用,并且只是为了与Interix兼容而存在,在这种情况下,Interix是唯一一个读取或写入安全描述符的人,因此可以执行任何操作。 :) :)
D:PAI : The DACL is DACL_PROTECTED (doesn't inherit permissions from parents) and DACL_AUTO_INHERIT (participates in the normal permissions inheritance system; eg children of this filesystem object will inherit permissions from this) D:PAI :DACL是DACL_PROTECTED (不继承父项的权限)和DACL_AUTO_INHERIT (参与普通权限继承系统;例如,此文件系统对象的子项将继承此权限)

  • (A;;WD;;;WD) : Grant WRITE_DAC (permission to change the DACL part of the security descriptor) access to WORLD\\EVERYONE . (A ;; WD ;;; WD) :授予WRITE_DAC (更改安全描述符的DACL部分的权限)访问WORLD\\EVERYONE Hmm, WRITE_DAC isn't read, write, or execute, so what would we do there? 嗯, WRITE_DAC不是读,写或执行的,那么我们在那里做什么呢?
  • (A;;FA;;;S-1-5-21-2127521184-1604012920-1887927527-9342113) : Grant FILE_ALL_ACCESS to REDMOND\\bion . (A ;; FA ;;; S-1-5-21-2127521184-1604012920-1887927527-9342113) :向REDMOND\\bion bion授予FILE_ALL_ACCESS Note that I am not the owner, the group owner, or "others" so how would you map this? 请注意,我不是所有者,群组所有者或“其他人”,所以您如何映射这个?
  • (A;;0x4;;;BA) Grant FILE_APPEND_DATA to BUILTIN\\ADMINISTRATORS . (A ;; 0x4 ;;; BA)FILE_APPEND_DATA授予BUILTIN\\ADMINISTRATORS That's kind of like write, but doesn't allow you to change content already in the file... 这有点像写,但不允许您更改文件中已有的内容...

(And I'm leaving out a bunch of stuff like Mandatory Access Control....) (而且我遗漏了一些像强制访问控制......的东西。)

I'm not saying that we couldn't try to do better at this mapping, but if you need to do nontrivial permissions work the <filesystem> TS can't really help you on systems that support access control lists. 我不是说我们不能尝试在这种映射上做得更好,但是如果你需要做非常重要的权限工作,那么<filesystem> TS对于支持访问控制列表的系统无法真正帮助你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM