Невозможно скопировать файл, даже если в C # предоставлено разрешение FileIOPermission.

Я пробовал FileIOPermission в Windows 7 в .NET 3.5. Я был пользователем Windows XP, и мне было предоставлено это разрешение, поскольку я был администратором

Я написал следующий код, проверяя, могу ли я писать в C: \ Program Files \ Outlook ......

static void Main(string[] args)
{
    Console.WriteLine("Am I an administrator? " + new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator);

    //  Try and open a file in C:\Program Files\Microsoft Office\Office14\BCSLaunch.dll
    string path = @"C:\Program Files\Microsoft Office\Office14\BCSLaunch.dll";

    try
    {
        FileIOPermission ioPerm = new FileIOPermission(FileIOPermissionAccess.Read, path);
        ioPerm.Demand();

        string backupPath = Path.ChangeExtension(path, ".bak");
        FileIOPermission writeAccess = new FileIOPermission(FileIOPermissionAccess.AllAccess, backupPath);
        writeAccess.Demand();

        Console.WriteLine("Read access is permitted: {0} => {1}",path,SecurityManager.IsGranted(ioPerm));
        Console.WriteLine("Write backup file is permitted: {0} => {1}", backupPath, SecurityManager.IsGranted(writeAccess));

        File.Copy(path, backupPath);

        Console.WriteLine("File copied! {0}",backupPath);
        Console.WriteLine("Deleting file.....");
        File.Delete(path);
    }
    catch (UnauthorizedAccessException uae)
    {
        Console.WriteLine(uae.ToString());
    }

    Console.ReadLine();
}

Итак, программа вызывает UnauthorizedAccessException (чего я ожидал), но я не понимаю, что Demand() разрешает разрешение, SecurityManager подтверждает, что разрешение предоставлено, но при выполнении File.Copy() я получаю исключение.

Хотя я рад видеть, что .NET останавливает меня, почему он не уведомил меня раньше, когда я позвонил Demand()?

Получаю следующий результат:

Am I an administrator? False
Read access is permitted: C:\Program Files\Microsoft Office\Office14\BCSLaunch.dll => True
Write backup file is permitted: C:\Program Files\Microsoft Office\Office14\BCSLaunch.bak => True
System.UnauthorizedAccessException: Access to the path 'C:\Program Files\Microsoft Office\Office14\BCSLaunch.bak' is denied.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite)
   at System.IO.File.Copy(String sourceFileName, String destFileName)
   at TryAndGetUACPrompt.Program.Main(String[] args) in C:\Users\..............

Пожалуйста, помогите мне понять, почему я получаю противоречивую информацию?

--

Обновление - 19:30 GMT

Я просмотрел ACL исходного файла, используя следующий код:

Console.WriteLine("ACL Permissions for Source....");
FileSecurity fileSecurityForOriginalPath = new FileSecurity(path, AccessControlSections.Access);

foreach (FileSystemAccessRule rule in fileSecurityForOriginalPath.GetAccessRules(true,true,typeof(NTAccount)))
{
   Console.WriteLine("{0} => {1}", rule.FileSystemRights, rule.AccessControlType);
}

Результат выглядит следующим образом:

ACL Permissions for Source....
FullControl => Allow
FullControl => Allow
ReadAndExecute, Synchronize => Allow

Таким образом, у меня есть доступ, чтобы прочитать это. Однако я попытался использовать этот код для просмотра разрешений пути к резервной копии и очевидно, я получаю исключение, поскольку мой файл резервной копии (назначения) физически не существует, поэтому я не могу проверить разрешения в теме.

Затем я попробую другое предложение, чтобы переместить эту проверку в другой метод.

Обновление - 19:45 GMT

Я переработал требования чтения / записи в другой метод:

private static FileIOPermission CheckWriteAccess(string backupPath)
{
    FileIOPermission writeAccess = new FileIOPermission(FileIOPermissionAccess.AllAccess, backupPath);
    writeAccess.Demand();
    return writeAccess;
}

private static FileIOPermission CheckReadAccess(string path)
{
    FileIOPermission ioPerm = new FileIOPermission(FileIOPermissionAccess.Read, path);
    ioPerm.Demand();
    return ioPerm;
}

Оба без исключения возвращают штраф.

Поэтому, если .NET Security дополняет DACL, мне интересно, почему он думает, что это будет успешным, если на самом деле это не так.

--

Обновление 19:57 GMT

Хорошо, я проверил разрешения каталога, а не backupFile (файл назначения), и получил это как результат (используя foreach в AuthorizationRuleCollection из .GetAccessRules ())

Checking write access in this directory....
FullControl => Allow
268435456 => Allow
FullControl => Allow
268435456 => Allow
FullControl => Allow
268435456 => Allow
ReadAndExecute, Synchronize => Allow
-1610612736 => Allow
268435456 => Allow

Я использовал Enum.Format(typeof(FileSystemAccessRights),rule,"G") для форматирования, эффективно выполняя ToString (), но я просто не был уверен, что эти числа верны.

Код для вывода вышеуказанного:

private static DirectorySecurity CheckWriteAccess(string backupPath)
{
    DirectorySecurity writeAccess = new DirectorySecurity( Path.GetDirectoryName(backupPath),AccessControlSections.Access);

    Console.WriteLine("Checking write access in this directory....");
    foreach (FileSystemAccessRule rule in writeAccess.GetAccessRules(true, true, typeof(NTAccount)))
    {
        Console.WriteLine("{0} => {1}", Enum.Format(typeof(FileSystemRights),rule.FileSystemRights,"G"), rule.AccessControlType);
    }

    return writeAccess;
}

person Dominic Zukiewicz    schedule 27.01.2010    source источник
comment
Доступ предотвращает не среда выполнения .NET, а файловая система.   -  person dtb    schedule 27.01.2010
comment
Вы просто перечисляете правила (запись управления доступом / ACE) в ACL файла / папки (список управления доступом), но не обращаете внимания на то, какому пользователю предоставлено какое право . Например, вы показываете "Разрешить", "Разрешить" и т. Д., Но не показываете кому разрешено. Каждый ACE в ACL описывает принципала (пользователя или группу) и их права (r / w / x и т. Д.). Вы все еще не показали, что пользователь, который запускает программу (вы?), Имеет ACE с полным контролем над ресурсом, к которому вы пытаетесь получить доступ.   -  person x0n    schedule 17.09.2010
comment
какое окончательное решение с образцом исходного кода?   -  person Kiquenet    schedule 22.11.2011
comment
Решение в том, что моя проблема заключается в безопасности Windows, а не в .NET. .NET было предоставлено разрешение на доступ к файлу (не было отказано в декларативной безопасности), а Windows - нет. Надеюсь, это поможет.   -  person Dominic Zukiewicz    schedule 22.11.2011


Ответы (1)


Разрешение CAS IOP на чтение и запись только дает вам возможность читать или писать. Он не обращает внимания на разрешения на уровне файловой системы (ACL). Изучите ACL в папке поближе :)

-Oisin

person x0n    schedule 27.01.2010
comment
также может случиться так, что вы не можете ПРОЧИТАТЬ DLL, потому что она открыта исключительно процессом. - person x0n; 27.01.2010
comment
Я думаю, это приведет к IOException, а не UnauthorizedAccessException. (Хотя +1 за ответ) - person Fredrik Mörk; 27.01.2010
comment
Итак, вы говорите, что .NET не имеет каких-либо ограничений для пользователей из среды CLR, которые ограничивали бы доступ, поэтому мне разрешено. НО ... тогда я должен напрямую опросить файловую систему, а затем посмотреть, блокирует ли это ее? - person Dominic Zukiewicz; 16.09.2010
comment
@dominic - да. В системе CLR CAS реализована так называемая песочница. Чтобы использовать аналогию, он решает, позволит или не позволит вам попытаться открыть дверь (IOPermission) в зависимости от правил безопасности (Evidence). Однако, когда вы пытаетесь открыть дверь, вы обнаруживаете, что она заблокирована (ACL). - person x0n; 17.09.2010