FileSystemRights :(
От: Пельмешко Россия blog
Дата: 20.12.09 10:38
Оценка:
Здравствуйте, господа!

Нужно чтобы это:

    public static IEnumerable<FileInfo> Traverse(DirectoryInfo dir, string pattern)
    {
      foreach (var file in dir.GetFiles(pattern))
      {
        yield return file;
      }

      foreach (var sub in dir.GetDirectories())
      {
        foreach (var file in Traverse(sub, pattern))
        {
          yield return file;
        }
      }
    }

Не падало из-за того, что некоторые директории неподвластны для просмотра текущему пользователю...

Просто ловить UnauthorizedAccessException счёл некошерным, стал разбираться с правами доступа...
И тут же упёрся в "C:\Documents and settings" (Windows7 RC)...

    var principal = new WindowsPrincipal(WindowsIdentity.GetCurrent());

    var rules =
      new DirectoryInfo("C:\\Documents and settings")
      .GetAccessControl(AccessControlSections.Access)
      .GetAccessRules(true, true, typeof(NTAccount));

    foreach (FileSystemAccessRule rule in rules)
    {
      if (principal.IsInRole(rule.IdentityReference.Value))
      {
        Console.WriteLine("User: '{0}'", rule.IdentityReference.Value);
        Console.WriteLine("{0}: '{1}'", rule.AccessControlType, rule.FileSystemRights);
      }
    }

Говорит:

User: 'Все'
Deny: 'ReadData'
User: 'Все'
Allow: 'ReadAndExecute, Synchronize'


Вроде достаточно требований чтобы сделать DirectoryInfo.GetFiles(), но оно падает...
Объясните, пожалуйста, как просто проверить, есть у меня доступ на получение списка файлов и директорий, или нет...

p.s. Не понимаю что приоритетенее, allow или deny... порядок rules что ли важен?
p.p.s. Из Explorer'а тоже Documents and settings не открыть: "отказано в доступе".
p.p.p.s. Извините, если подобная тема поднималась, не нагуглилось ничего конкретного, всем советуют exception'ы ловить...
Re: FileSystemRights :(
От: Jolly Roger  
Дата: 20.12.09 12:41
Оценка: 27 (1) +1
Здравствуйте, Пельмешко, Вы писали:

П>Здравствуйте, господа!


И Вам не болеть!

П>Объясните, пожалуйста, как просто проверить, есть у меня доступ на получение списка файлов и директорий, или нет...


Лучший способ — попробовать открыть, запросив минимально необходимый набрав.

П>p.s. Не понимаю что приоритетенее, allow или deny... порядок rules что ли важен?


Принцип прост — кто первый встал, того и тапки

ACE проверяются в порядке их следования в ACL. На "входе" все запрошенные права помечаются как undefined. Берётся первый ACE и проверяется, применим ли он к проверяемой учётке (по SID). Если не применим, берётся следующий. Если применим, то имеющиеся в нём права сравниваются с запрошенными. Каждое найденное помечается в соответствии с типом ACE — allowed or denied. Если по результату будет хотя-бы одно право помечено как denied, то проверка заканчивается с отказом в доступе. Если отказов нет и не осталось ни одного undefined, то проверка прекращается с результатом "разрешено". В противном случае берётся следующий ACE и тд.

Для ACL есть такое понятие — canonical order. В соответствии с ним, разрешающие ACE должены располагаться после запрещающих, при этом разрешающие ACE носят как-бы обобщённый характер, а запрещающие — уточняющий. То есть разрешаем доступ группе Users, а запрещаем конкретно Васе Пупкину Следовать ему никто не обязывает напрямую, но лучше соблюдать — избавит от лишней головной боли.
http://files.rsdn.org/82987/Img.GIF "Нормальные герои всегда идут в обход!"
Re: FileSystemRights :(
От: Dzirt2005  
Дата: 20.12.09 14:47
Оценка:
Здравствуйте, Пельмешко, Вы писали:

[...]
П>p.s. Не понимаю что приоритетенее, allow или deny... порядок rules что ли важен?
На NTFS Deny имеет приоритет над Allow.

П>p.p.s. Из Explorer'а тоже Documents and settings не открыть: "отказано в доступе".

Естественно. У нее в правах стоит запрет на "Содержимое папки/Чтение данных"
Re: FileSystemRights :(
От: x64 Россия http://x64blog.name
Дата: 20.12.09 16:20
Оценка:
П>p.s. Не понимаю что приоритетенее, allow или deny... порядок rules что ли важен?

Вообще deny, выше уже объяснили развёрнуто.
JID: x64j@jabber.ru
Re: FileSystemRights :(
От: Кирилл Осенков Украина http://blogs.msdn.com/b/kirillosenkov
Дата: 21.12.09 08:14
Оценка:
Кстати надо бы перформанс итераторов в твоём случае проверить — не помню точно, но вложенные итераторы в некоторых случаях тормозят квадратично:
http://blogs.msdn.com/wesdyer/archive/2007/03/23/all-about-iterators.aspx

Я бы здесь лучше CPS использовал — передавал бы Action<FileInfo> fileInfoProcessor как параметр. Правда ленивость уйдёт. Но про Rx ты видео тоже смотрел

Ещё чем не нравится overload http://msdn.microsoft.com/en-us/library/ms143316.aspx

А в 4.0 есть ещё Directory.EnumerateFiles — http://msdn.microsoft.com/en-us/library/system.io.directory.enumeratefiles(VS.100).aspx (можно рефлектором посмотреть, как оно сделано)

P.S. А по теме — я бы ловил exception и не заморачивался Хотя стремление уважаю
Re[2]: FileSystemRights :(
От: _FRED_ Россия
Дата: 21.12.09 08:23
Оценка:
Здравствуйте, Кирилл Осенков, Вы писали:

КО>P.S. А по теме — я бы ловил exception и не заморачивался Хотя стремление уважаю


Кстати, интересно посмотреть, на среднестатистическом диске С: при обходе всех папок под обычным пользователем сколько времени потеряется на catch и всё, что с ним связано… Если действительно не много, я бы тоже "плакал и лез на кактус"
Help will always be given at Hogwarts to those who ask for it.
Re: FileSystemRights :(
От: Sinix  
Дата: 21.12.09 08:48
Оценка: 39 (2) +1
Здравствуйте, Пельмешко, Вы писали:

П>Просто ловить UnauthorizedAccessException счёл некошерным, стал разбираться с правами доступа...

П>И тут же упёрся в "C:\Documents and settings" (Windows7 RC)...

Это хардлинк, его можно спокойно пропустить (если придумаете как ).

Свои пять копеек:
Безопасность в windows — штука крайне своеобразная и без прочтения хотя бы соответствующей главы из windows internals туда лучше не лезть.
Предупреждаю сразу, книга читается довольно тяжело (из сравнимых по объёму — Дейт воспринимается куда легче), по крайней мере оригинал — по висте русскоязычного издания пока нет.

К сожалению, в .Net нет метода GetEffectivePermissions и гугл не знает о готовых решениях. Без него проверять очень тяжело — у потока может быть слегка урезанный токен, эффект от виртуализации (читай uac) и тыды и тыпы.
http://www.mcmcse.com/microsoft/guides/ntfs_and_share_permissions.shtml

Keep in mind that priveledges (rights) can sometimes override permissions.

ххых

Плюс, даже готовое api временами лажает (как минимум в win 2008 sp1) — вкладка "действующие разрешения" некорректно показывает разрешения, если доменный пользователь включён в локальную группу + ещё какое-то условие (так и не выяснил, предположение — owner не входит в эту группу).

Так что проще ловить исключения, уж поверьте. А ещё лучше — не ловить, а откатывать в finally (если !succeed, разумеется).

Ещё ссылок по теме:
http://www.tech-faq.com/nt-file-system-permissions.shtml
http://stackoverflow.com/questions/1281620/checking-for-directory-and-file-write-permissions-in-net
http://groups.google.co.uk/group/microsoft.public.dotnet.languages.csharp/browse_thread/thread/ef5ceaf72827c69d/208347aa99a2de3b?#208347aa99a2de3b

и по общей матчасти:
http://alt.pluralsight.com/wiki/default.aspx/Keith.GuideBook.HomePage
Re[2]: FileSystemRights :(
От: Jolly Roger  
Дата: 21.12.09 13:54
Оценка: 39 (3)
Здравствуйте, Sinix, Вы писали:

S>К сожалению, в .Net нет метода GetEffectivePermissions и гугл не знает о готовых решениях.


Может Вы имели в виду GetEffectiveRightsFromAcl? То есть типа этого?

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct Trustee
        {
            public IntPtr pMultipleTrustee;
            public int MultipleTrusteeOperation;
            public int TrusteeForm;
            public int TrusteeType;
            [MarshalAs(UnmanagedType.LPTStr)]
            public string name;
        }

        [DllImport("advapi32.dll", CharSet = CharSet.Unicode)]
        internal static extern int GetEffectiveRightsFromAclW(
            byte[] pAcl, ref Trustee pTrustee, out uint pAccessMask);


            FileSecurity fss = new FileSecurity(
                "SomeFile.bin", AccessControlSections.Access);
            byte[] rawsd = fss.GetSecurityDescriptorBinaryForm();
            CommonSecurityDescriptor csd 
                = new CommonSecurityDescriptor(true, false, rawsd, 0);
            int aclLen = csd.DiscretionaryAcl.BinaryLength;
            byte[] rawAcl = new byte[aclLen];
            csd.DiscretionaryAcl.GetBinaryForm(rawAcl, 0);
            uint mask;
            Trustee trustee = new Trustee();
            trustee.TrusteeForm = 1;
            trustee.TrusteeType = 1;
            trustee.name = "SomeUser";
            int result = GetEffectiveRightsFromAclW(rawAcl, ref trustee, out mask);
            if (result == 0)
                Console.WriteLine((FileSystemRights)mask);
            else
                Console.WriteLine("Error: {0}", result);
http://files.rsdn.org/82987/Img.GIF "Нормальные герои всегда идут в обход!"
Re[2]: FileSystemRights :(
От: Пельмешко Россия blog
Дата: 21.12.09 19:42
Оценка:
Здравствуйте, Кирилл Осенков, Вы писали:

КО>Кстати надо бы перформанс итераторов в твоём случае проверить — не помню точно, но вложенные итераторы в некоторых случаях тормозят квадратично:

КО>http://blogs.msdn.com/wesdyer/archive/2007/03/23/all-about-iterators.aspx

Я знал на что я иду... у меня каждый раз слёза наворачивается, когда yield в ещё один foreach засунуть приходится...
Ага, очень жаль что в C# 4.0 не будет yield foreach, тогда бы итераторы "тормозили линейно"...

КО>Я бы здесь лучше CPS использовал — передавал бы Action<FileInfo> fileInfoProcessor как параметр. Правда ленивость уйдёт. Но про Rx ты видео тоже смотрел


Ленивость нужна...

КО>Ещё чем не нравится overload http://msdn.microsoft.com/en-us/library/ms143316.aspx


Если по всему диску пустить (что я и делаю), то можно и не дождаться + падает из-за тех же прав...

КО>А в 4.0 есть ещё Directory.EnumerateFiles — http://msdn.microsoft.com/en-us/library/system.io.directory.enumeratefiles(VS.100).aspx (можно рефлектором посмотреть, как оно сделано)


Это было бы самое то, но я в рамках 3.5 + наверняка с правами тот же косяк...

КО>P.S. А по теме — я бы ловил exception и не заморачивался Хотя стремление уважаю


Эх
Re[3]: FileSystemRights :(
От: _FRED_ Россия
Дата: 21.12.09 20:04
Оценка:
Здравствуйте, Jolly Roger, Вы писали:

S>>К сожалению, в .Net нет метода GetEffectivePermissions и гугл не знает о готовых решениях.


JR>Может Вы имели в виду GetEffectiveRightsFromAcl? То есть типа этого?


Я так понимаю, что это всё равно "бабушка надвое сказала"

The GetEffectiveRightsFromAcl function does not consider the following:

  • Implicitly granted access rights, such as READ_CONTROL and WRITE_DAC, for the owner of an object when determining effective rights.
  • Privileges held by the trustee when determining effective access rights.
  • Group rights associated with the logon session, such as interactive, network, authenticated users, and so forth, in determining effective access rights.
  • Resource manager policy. For example, for file objects, Delete and Read attributes can be provided by the parent even if they have been denied on the object.

    The GetEffectiveRightsFromAcl function fails and returns ERROR_INVALID_ACL if the specified ACL contains an inherited access-denied ACE.

  • здесь
    Help will always be given at Hogwarts to those who ask for it.
    Re[4]: FileSystemRights :(
    От: Пельмешко Россия blog
    Дата: 21.12.09 20:14
    Оценка: :)
    Здравствуйте, _FRED_, Вы писали:

    _FR>Здравствуйте, Jolly Roger, Вы писали:


    S>>>К сожалению, в .Net нет метода GetEffectivePermissions и гугл не знает о готовых решениях.


    JR>>Может Вы имели в виду GetEffectiveRightsFromAcl? То есть типа этого?


    _FR>Я так понимаю, что это всё равно "бабушка надвое сказала"


    Вот только что на это нарвался, на каталоге C:\MSOCache... Не далеко уехал от Documents and Settings...
    Re[3]: FileSystemRights :(
    От: Sinix  
    Дата: 22.12.09 01:17
    Оценка:
    Здравствуйте, Jolly Roger, Вы писали:

    Спс! Действительно, первым делом надо было поискать на www.pinvoke.net.

    Осталось получить привелегии
    Матчасть: http://msdn.microsoft.com/en-us/library/aa379306(VS.85).aspx
    Константы: http://msdn.microsoft.com/en-us/library/bb530716(VS.85).aspx

    при помощи
    GetTokenInformation
    (http://msdn.microsoft.com/en-us/library/aa446671(VS.85).aspx)

    и посчитать по тем же правилам, что и windows.
    Re[4]: FileSystemRights :(
    От: Jolly Roger  
    Дата: 22.12.09 01:58
    Оценка:
    Здравствуйте, _FRED_, Вы писали:

    _FR>Я так понимаю, что это всё равно "бабушка надвое сказала"


    Да, так и есть. С этими высокоуровневыми надстройками в security вообще беда. Я из-них ещё на W2k несколько раз на грабли наступал, было больно Потому изначально и советовал — лучше просто пробовать открыть. В нативе-то отказ фактически ничего не стоит, а вот в NET, боюсь, обилие исключений способно совсем затормозить Может стоит просто импортировать FindFirstFile etc и не мучиться
    http://files.rsdn.org/82987/Img.GIF "Нормальные герои всегда идут в обход!"
    Re[5]: FileSystemRights :(
    От: Sinix  
    Дата: 22.12.09 03:25
    Оценка:
    Здравствуйте, Jolly Roger, Вы писали:

    JR>Здравствуйте, _FRED_, Вы писали:


    _FR>>Я так понимаю, что это всё равно "бабушка надвое сказала"


    JR> В нативе-то отказ фактически ничего не стоит, а вот в NET, боюсь, обилие исключений способно совсем затормозить


    Хз. У вас есть возможность проверить? В теории достаточно интеропнуть CreateFile (http://msdn.microsoft.com/en-us/library/aa363858.aspx) — лень вспоминать все нюансы с оверхедом интеропа.

    JR>Может стоит просто импортировать FindFirstFile etc и не мучиться

    Еще, как вариант
    File.SetLastAccessTime(path, File.GetLastAccessTime(path));


    Работает и для файлов, и для папок.
    Re[6]: FileSystemRights :(
    От: Jolly Roger  
    Дата: 22.12.09 04:22
    Оценка: +1
    Здравствуйте, Sinix, Вы писали:

    S>Хз. У вас есть возможность проверить? В теории достаточно интеропнуть CreateFile (http://msdn.microsoft.com/en-us/library/aa363858.aspx) — лень вспоминать все нюансы с оверхедом интеропа.


    Честно говоря, со временем не очень Исключения, они и в нативном коде обходятся дорого, я прикидывал — несколько тысяч инструкций при глубине вложенности фреймов = 1.

    Думал тут, упоминать-нет про AccessCheck, решил всё-же написать Она хороша для проверки разрешений на приватный объект, но и здесь, вероятно, можно попробовать. Требует токена имперсонации — решаемо хотя-бы с помощью ImpersonateSelf. Хуже то, что для использования generic масок нужна заполненная GENERIC_MAPPING, а как её получить для системных объектов, мне неизвестно. Но в принципе можно обойтись набором из standard rights. В общем, попробовать можно.
    http://files.rsdn.org/82987/Img.GIF "Нормальные герои всегда идут в обход!"
    Re[7]: FileSystemRights :(
    От: Sinix  
    Дата: 22.12.09 04:42
    Оценка:
    Здравствуйте, Jolly Roger, Вы писали:

    JR>Честно говоря, со временем не очень Исключения, они и в нативном коде обходятся дорого, я прикидывал — несколько тысяч инструкций при глубине вложенности фреймов = 1.


    Блин, меня самого корёжит, когда обсуждаешь _возможную_ производительность видами по воде)
    Чуть-чуть сфероконей: если вычисление разрешений не обходится побитовыми операциями, то относительная стоимость исключения будет мизерной.

    JR>В общем, попробовать можно.

    +1
    Что-то кажется мне, что это классический неуловимый джо...
     
    Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.