Domanda

Abbiamo recentemente stati costretti a passare a un nuovo server di dominio a metà strada in tutto il mondo. Questo può non sembrare molto di un cambiamento, ma uno dei processi che si corre spesso è improvvisamente andato formare un comando di 2 secondi a un comando 5 minuti.

Il motivo? Stiamo aggiornando le autorizzazioni per molte directory sulla base di un "modello" struttura di directory.

Abbiamo scoperto che XCOPY può aggiornare la maggior parte di queste impostazioni nella finestra stesso-vecchio-due secondi. Le impostazioni rimanenti, ovviamente, vengano lasciate fuori.

Quello che sto cercando di capire è, come può XCopy fare più velocemente quanto NET classi di sicurezza dovrebbero fare in modo nativo? Ovviamente mi manca qualcosa.

Qual è il metodo migliore per copiare le informazioni ACL di una directory senza il ping (o ping minima) il / server Active Directory di dominio?

Ecco quello che ho:

    ... 

    DirectorySecurity TemplateSecurity = new DirectorySecurity(TemplateDir, AccessControlSections.All);

    ... 


    public static void UpdateSecurity(string destination, DirectorySecurity TemplateSecurity)
    {
        DirectorySecurity dSecurity = Directory.GetAccessControl(destination);

        // Remove previous security settings. (We have all we need in the other TemplateSecurity setting!!)
        AuthorizationRuleCollection acl_old = dSecurity.GetAccessRules(true, true, typeof(NTAccount));
        foreach (FileSystemAccessRule ace in acl_old)
        {
            // REMOVE IT IF YOU CAN... if you can't don't worry about it.
            try
            {
                dSecurity.RemoveAccessRule(ace);
            }
            catch { }
        }

        // Remove the inheritance for the folders... 
        // Per the business unit, we must specify permissions per folder.
        dSecurity.SetAccessRuleProtection(true, true);

        // Copy the permissions from TemplateSecurity to Destination folder.
        AuthorizationRuleCollection acl = TemplateSecurity.GetAccessRules(true, true, typeof(NTAccount));

        foreach (FileSystemAccessRule ace in acl)
        {
            // Set the existing security.
            dSecurity.AddAccessRule(ace);

            try
            {
                // Remove folder inheritance...
                dSecurity.AddAccessRule(new FileSystemAccessRule(
                    ace.IdentityReference, ace.FileSystemRights,
                    InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
                    PropagationFlags.None,
                    ace.AccessControlType));
            }
            catch { }
        }

        // Apply the new changes.
        Directory.SetAccessControl(destination, dSecurity);
    }

È stato utile?

Soluzione

Va bene ... Ho un prototipo funzionante dopo una tonnellata di SCAVA su internet. Inutile dire che ci sono un sacco di mis-informazioni su ACL on-line. Io non sono esattamente sicuro se questo po 'di informazioni sarà una manna dal cielo, o più mis-informazione. Dovrò lasciare che per voi, l'utente, di decidere.

Quello che ho finito con è pulita, liscia, e molto, molto veloce in quanto non sempre TOCCARE server di dominio. Sto copiando direttamente le voci SDDL. Aspetta, tu dici ... non si può fare che in una directory perché si ottiene l'errore SeSecurityPrivilege temuto!

No, se si limita la copia soltanto liste di controllo di accesso (ACL).

Ecco il codice:

    public static void UpdateSecurity(string destination, DirectorySecurity templateSecurity)
    {
        DirectorySecurity dSecurity = Directory.GetAccessControl(destination);

        string sddl = templateSecurity.GetSecurityDescriptorSddlForm(AccessControlSections.Access);
        try
        {
            // TOTALLY REPLACE The existing access rights with the new ones.
            dSecurity.SetSecurityDescriptorSddlForm(sddl, AccessControlSections.Access);

            // Disable inheritance for this directory.
            dSecurity.SetAccessRuleProtection(true, true);


            // Apply these changes.
            Directory.SetAccessControl(destination, dSecurity);
        }
        catch (Exception ex)
        {
            // Note the error on the console... we can formally log it later.
            Console.WriteLine(pth1 + " : " + ex.Message);
        }


        // Do some other settings stuff here...

    }

Si notino le bandiere AccessControlSections.Access sui metodi SDDL. Questa è stata la chiave magica per far funzionare il tutto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top