2010-06-25 4 views
0

J'ai trouvé une méthode pour copier les informations d'autorisations ntfs d'un dossier existant vers un dossier nouvellement créé - je ne suis pas sûr qu'il fasse le travail qu'il devrait faire. Peut-être que l'on peut jeter un oeil à la méthode et donner quelques commentaires:Comment copier les permissions ntfs

private static void CopySecurityInformation(String source, String dest) 
{ 
    FileSecurity fileSecurity = File.GetAccessControl(
     source, 
     AccessControlSections.All); 
    FileAttributes fileAttributes = File.GetAttributes(source); 
    File.SetAccessControl(dest, fileSecurity); 
    File.SetAttributes(dest, fileAttributes); 
} 

Merci pour votre aide, Daniel

Répondre

1

Il fait un peu plus que simplement copier les autorisations NTFS. Il copie également les attributs du fichier. Cependant, je ne suis pas certain de copier les permissions héritées, mais de les lancer une fois et vous devriez être capable de le découvrir. Notez que la copie des autorisations nécessite des autorisations spéciales (les administrateurs disposent de ces droits, bien entendu). Assurez-vous que le processus exécutant cette méthode dispose des autorisations requises pour interroger, afficher et définir les autorisations sur ces objets.

+0

Les autorisations de copie des attributs _and_ étaient exactement le comportement que je voulais atteindre. - désolé je ne vous l'ai pas dit avant; ...-) Et oui, l'application s'assure que le compte administrateur est utilisé. – dhh

2

J'ai essayé de suivre le modèle suggéré OP pour copier les ACL et les attributs d'un fichier et j'ai trouvé quelques problèmes dans notre application. Espérons que cette information aide les autres.

Selon MSDN, l'utilisation de la méthode File.SetAccessControl() comme indiqué ci-dessus ne fonctionnera pas.

La méthode SetAccessControl persiste uniquement les objets FileSecurity qui ont été modifiés après la création de l'objet. Si un objet FileSecurity n'a pas été modifié, il ne sera pas conservé dans un fichier. Par conséquent, il n'est pas possible de récupérer un objet FileSecurity à partir d'un fichier et réappliquer le même objet à un autre fichier.

Il est nécessaire de faire un nouvel objet FileSecurity pour le fichier de destination et attribuer à cette une copie de la source objet FileSecurity.

Voici un exemple d'un modèle qui fonctionne à partir de notre application. Après avoir corrigé le premier problème, nous avons constaté que l'attribut propriétaire n'était pas copié. Au lieu de cela, le fichier de destination appartenait à l'administrateur dans notre cas. Pour contourner ce problème, le processus doit activer le privilège SE_RESTORE_NAME. Découvrez AdjustTokenPrivileges sur pinvoke.net pour une classe Privileges complète qui facilite les privilèges de configuration.

La dernière chose que nous avons dû faire était UAC. Nous devions redémarrer notre application avec des droits d'administration si l'utilisateur s'exécutait sous UAC. Voici un autre exemple de notre application qui traite de relancer l'application avec des privilèges élevés.

private static void RelaunchWithAdministratorRights(string[] args) 
    { 
     // Launch as administrator 
     ProcessStartInfo processStartInfo = new ProcessStartInfo(); 
     processStartInfo.UseShellExecute = true; 
     processStartInfo.WorkingDirectory = Environment.CurrentDirectory; 
     string executablePath = System.Reflection.Assembly.GetExecutingAssembly().Location; 
     processStartInfo.FileName = executablePath; 
     processStartInfo.Verb = "runas"; 

     if (args != null && args.Count() > 0) 
     { 
      string arguments = args[0]; 
      for (int i = 1; i < args.Count(); i++) 
       arguments += " " + args[i]; 
      processStartInfo.Arguments = arguments; 
     } 

     try 
     { 
      using (Process exeProcess = Process.Start(processStartInfo)) 
      { 
       exeProcess.WaitForExit(); 
      } 
     } 
     catch 
     { 
      // The user refused to allow privileges elevation. Do nothing and return directly ... 
     } 

     Environment.Exit(0); 
    } 

nôtre était une application console donc nous avons besoin de passer le paramètre args de la méthode Main au RelaunchWithAdministratorRights(args). Les applications non-console peuvent passer null à la place. Nous lançons un appel RelaunchWithAdministratorRights à l'intérieur catch blocs comme dans:

 try 
     { 
      ... 
     } 
     catch (SecurityException) 
     { 
      RelaunchWithAdministratorRights(args); 
      return; 
     } 

Dans notre application nous revenons juste après l'appel à RelaunchWithAdministratorRights pour quitter l'instance de l'application qui ne disposaient pas de privilèges. En fonction de votre application, vous préférerez peut-être throw votre sortie.Quoi qu'il en soit, après le retour de RelaunchWithAdministratorRights vous ne voulez pas que cette instance continue le traitement.

Profitez-en!

+0

Très ancienne question - mais merci beaucoup Gyle pour partager vos propres résultats. – dhh

Questions connexes