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);
}
}
Вроде достаточно требований чтобы сделать DirectoryInfo.GetFiles(), но оно падает...
Объясните, пожалуйста, как просто проверить, есть у меня доступ на получение списка файлов и директорий, или нет...
p.s. Не понимаю что приоритетенее, allow или deny... порядок rules что ли важен?
p.p.s. Из Explorer'а тоже Documents and settings не открыть: "отказано в доступе".
p.p.p.s. Извините, если подобная тема поднималась, не нагуглилось ничего конкретного, всем советуют exception'ы ловить...
Здравствуйте, Пельмешко, Вы писали:
П>Здравствуйте, господа!
И Вам не болеть!
П>Объясните, пожалуйста, как просто проверить, есть у меня доступ на получение списка файлов и директорий, или нет...
Лучший способ — попробовать открыть, запросив минимально необходимый набрав.
П>p.s. Не понимаю что приоритетенее, allow или deny... порядок rules что ли важен?
Принцип прост — кто первый встал, того и тапки
ACE проверяются в порядке их следования в ACL. На "входе" все запрошенные права помечаются как undefined. Берётся первый ACE и проверяется, применим ли он к проверяемой учётке (по SID). Если не применим, берётся следующий. Если применим, то имеющиеся в нём права сравниваются с запрошенными. Каждое найденное помечается в соответствии с типом ACE — allowed or denied. Если по результату будет хотя-бы одно право помечено как denied, то проверка заканчивается с отказом в доступе. Если отказов нет и не осталось ни одного undefined, то проверка прекращается с результатом "разрешено". В противном случае берётся следующий ACE и тд.
Для ACL есть такое понятие — canonical order. В соответствии с ним, разрешающие ACE должены располагаться после запрещающих, при этом разрешающие ACE носят как-бы обобщённый характер, а запрещающие — уточняющий. То есть разрешаем доступ группе Users, а запрещаем конкретно Васе Пупкину Следовать ему никто не обязывает напрямую, но лучше соблюдать — избавит от лишней головной боли.
[...] П>p.s. Не понимаю что приоритетенее, allow или deny... порядок rules что ли важен?
На NTFS Deny имеет приоритет над Allow.
П>p.p.s. Из Explorer'а тоже Documents and settings не открыть: "отказано в доступе".
Естественно. У нее в правах стоит запрет на "Содержимое папки/Чтение данных"
Я бы здесь лучше CPS использовал — передавал бы Action<FileInfo> fileInfoProcessor как параметр. Правда ленивость уйдёт. Но про Rx ты видео тоже смотрел
Здравствуйте, Кирилл Осенков, Вы писали:
КО>P.S. А по теме — я бы ловил exception и не заморачивался Хотя стремление уважаю
Кстати, интересно посмотреть, на среднестатистическом диске С: при обходе всех папок под обычным пользователем сколько времени потеряется на catch и всё, что с ним связано… Если действительно не много, я бы тоже "плакал и лез на кактус"
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, Пельмешко, Вы писали:
П>Просто ловить 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, разумеется).
Я знал на что я иду... у меня каждый раз слёза наворачивается, когда yield в ещё один foreach засунуть приходится...
Ага, очень жаль что в C# 4.0 не будет yield foreach, тогда бы итераторы "тормозили линейно"...
КО>Я бы здесь лучше CPS использовал — передавал бы Action<FileInfo> fileInfoProcessor как параметр. Правда ленивость уйдёт. Но про Rx ты видео тоже смотрел
Это было бы самое то, но я в рамках 3.5 + наверняка с правами тот же косяк...
КО>P.S. А по теме — я бы ловил exception и не заморачивался Хотя стремление уважаю
Здравствуйте, 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.
Здравствуйте, _FRED_, Вы писали:
_FR>Здравствуйте, Jolly Roger, Вы писали:
S>>>К сожалению, в .Net нет метода GetEffectivePermissions и гугл не знает о готовых решениях.
JR>>Может Вы имели в виду GetEffectiveRightsFromAcl? То есть типа этого?
_FR>Я так понимаю, что это всё равно "бабушка надвое сказала"
Вот только что на это нарвался, на каталоге C:\MSOCache... Не далеко уехал от Documents and Settings...
Здравствуйте, _FRED_, Вы писали:
_FR>Я так понимаю, что это всё равно "бабушка надвое сказала"
Да, так и есть. С этими высокоуровневыми надстройками в security вообще беда. Я из-них ещё на W2k несколько раз на грабли наступал, было больно Потому изначально и советовал — лучше просто пробовать открыть. В нативе-то отказ фактически ничего не стоит, а вот в NET, боюсь, обилие исключений способно совсем затормозить Может стоит просто импортировать FindFirstFile etc и не мучиться
Здравствуйте, Jolly Roger, Вы писали:
JR>Здравствуйте, _FRED_, Вы писали:
_FR>>Я так понимаю, что это всё равно "бабушка надвое сказала"
JR> В нативе-то отказ фактически ничего не стоит, а вот в NET, боюсь, обилие исключений способно совсем затормозить
Хз. У вас есть возможность проверить? В теории достаточно интеропнуть CreateFile (http://msdn.microsoft.com/en-us/library/aa363858.aspx) — лень вспоминать все нюансы с оверхедом интеропа.
JR>Может стоит просто импортировать FindFirstFile etc и не мучиться
Еще, как вариант
Здравствуйте, Sinix, Вы писали:
S>Хз. У вас есть возможность проверить? В теории достаточно интеропнуть CreateFile (http://msdn.microsoft.com/en-us/library/aa363858.aspx) — лень вспоминать все нюансы с оверхедом интеропа.
Честно говоря, со временем не очень Исключения, они и в нативном коде обходятся дорого, я прикидывал — несколько тысяч инструкций при глубине вложенности фреймов = 1.
Думал тут, упоминать-нет про AccessCheck, решил всё-же написать Она хороша для проверки разрешений на приватный объект, но и здесь, вероятно, можно попробовать. Требует токена имперсонации — решаемо хотя-бы с помощью ImpersonateSelf. Хуже то, что для использования generic масок нужна заполненная GENERIC_MAPPING, а как её получить для системных объектов, мне неизвестно. Но в принципе можно обойтись набором из standard rights. В общем, попробовать можно.
Здравствуйте, Jolly Roger, Вы писали:
JR>Честно говоря, со временем не очень Исключения, они и в нативном коде обходятся дорого, я прикидывал — несколько тысяч инструкций при глубине вложенности фреймов = 1.
Блин, меня самого корёжит, когда обсуждаешь _возможную_ производительность видами по воде)
Чуть-чуть сфероконей: если вычисление разрешений не обходится побитовыми операциями, то относительная стоимость исключения будет мизерной.
JR>В общем, попробовать можно.
+1
Что-то кажется мне, что это классический неуловимый джо...