PdActiveDirectory

PdActiveDirectory

using System;
using System.Collections.Generic;
using System.DirectoryServices;
using System.IO;
using System.Linq;
using System.Security.AccessControl;
using System.Text;

namespace PdMagic.Windows
{
    public class PdActiveDirectory
    {
        /*
        SCRIPT                         0x0001
        ACCOUNTDISABLE                 0x0002
        HOMEDIR_REQUIRED               0x0008
        LOCKOUT                        0x0010
        PASSWD_NOTREQD                 0x0020
        PASSWD_CANT_CHANGE             0x0040
        ENCRYPTED_TEXT_PWD_ALLOWED     0x0080
        TEMP_DUPLICATE_ACCOUNT         0x0100
        NORMAL_ACCOUNT                 0x0200
        INTERDOMAIN_TRUST_ACCOUNT      0x0800
        WORKSTATION_TRUST_ACCOUNT      0x1000
        SERVER_TRUST_ACCOUNT           0x2000
        DONT_EXPIRE_PASSWORD           0x10000
        MNS_LOGON_ACCOUNT              0x20000
        SMARTCARD_REQUIRED             0x40000
        TRUSTED_FOR_DELEGATION         0x80000
        NOT_DELEGATED                  0x100000
        USE_DES_KEY_ONLY               0x200000
        DONT_REQ_PREAUTH               0x400000
        PASSWORD_EXPIRED               0x800000
        TRUSTED_TO_AUTH_FOR_DELEGATION 0x1000000
         */

        public delegate void SetStatusCallback(string aStatus);

        private DirectoryEntry mActiveDirectory;

        public PdActiveDirectory()
        {
            mActiveDirectory = new DirectoryEntry("WinNT://" + Environment.MachineName + ",computer");
        }

        public static string CleanedException(Exception aException)
        {
            var lRealError = aException;
            var lMessages = aException.Message;

            while (lRealError.InnerException != null)
            {
                lRealError = lRealError.InnerException;
                lMessages += " | " + lRealError.Message;
            }

            return lMessages;
        }

        public void CreateLocalUserGroup(string aGroupName, string aDescription)
        {
            try
            {
                DirectoryEntry newGroup = mActiveDirectory.Children.Add(aGroupName, "group");
                newGroup.Invoke("Put", new object[] {"Description", aDescription});
                newGroup.CommitChanges();
            }
            catch (Exception lException)
            {
                throw new Exception("CreateLocalUserGroup", lException);
            }
        }

        public void CreateLocalUser(string aUserName, string aUserPassword, string aDescription)
        {
            try
            {
                try
                {
                    DirectoryEntry lUser = mActiveDirectory.Children.Add(aUserName, "user");
                    lUser.Invoke("SetPassword", new object[] {aUserPassword});
                    lUser.Invoke("Put", new object[] {"Description", aDescription});

                    int lUserFlags = 0;
                    if (lUser.Properties["userAccountControl"].Value != null)
                    {
                        lUserFlags = (int) lUser.Properties["userAccountControl"].Value;
                    }
                    lUser.Properties["UserFlags"].Value = lUserFlags | 0x10000 | 0x0040;
                    lUser.CommitChanges();
                }
                catch (Exception lCreateUser)
                {
                    throw new Exception("Create User", lCreateUser);
                }
            }
            catch (Exception lException)
            {
                throw new Exception("CreateLocalUser", lException);
            }
        }

        public bool GroupExists(string aGroupName)
        {
            try
            {
                mActiveDirectory.Children.Find(aGroupName, "group");
                return true;
            }
            catch
            {
                return false;
            }
        }


        public void AddUserToGroup(string aUserName, string aGroupName)
        {
            DirectoryEntry lUser;
            try
            {
                lUser = mActiveDirectory.Children.Find(aUserName, "user");
            }
            catch (Exception lFindUser)
            {
                throw new Exception("Find User", lFindUser);
            }

            DirectoryEntry lGroup;
            try
            {
                lGroup = mActiveDirectory.Children.Find(aGroupName, "group");
            }
            catch (Exception lFindGroup)
            {
                throw new Exception("Find Group", lFindGroup);
            }

            try
            {
                lGroup.Invoke("Add", new object[] {lUser.Path.ToString()});
                lGroup.CommitChanges();
            }
            catch (Exception lAddUserToGroup)
            {
                throw new Exception("AddUserToGroup", lAddUserToGroup);
            }
        }

        private static void ReplaceAllDescendantPermissionsFromObject(DirectoryInfo dInfo, DirectorySecurity dSecurity,
                                         SetStatusCallback aCallback)
        {
            // Copy the DirectorySecurity to the current directory
            dInfo.SetAccessControl(dSecurity);
            aCallback("Setting security on:" + dInfo.FullName);

            foreach (FileInfo fi in dInfo.GetFiles())
            {
                aCallback("Setting security on:" + fi.FullName);

                // Get the file's FileSecurity
                var ac = fi.GetAccessControl();

                // inherit from the directory
                ac.SetAccessRuleProtection(false, true);

                // apply change
              // fi.SetAccessControl(ac);
            }
            // Recurse into Directories
            dInfo.GetDirectories().ToList()
                 .ForEach(d => ReplaceAllDescendantPermissionsFromObject(d, dSecurity, aCallback ));
        }

        public void AddDirectorySecurity(string aDirectory, string aAccount,
                                         FileSystemRights aRights,
                                         AccessControlType aControlType,
                                         SetStatusCallback aCallback)
        {
            try
            {
                var lDirectoryInfo = new DirectoryInfo(aDirectory);
                DirectorySecurity lSecurity = lDirectoryInfo.GetAccessControl();
                lSecurity.AddAccessRule(new FileSystemAccessRule( aAccount, aRights, 
                                                                  InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
                                                                  PropagationFlags.InheritOnly, aControlType));
                lDirectoryInfo.SetAccessControl(lSecurity);
            }
            catch (Exception lException)
            {
                throw new Exception("AddDirectorySecurity", lException);
            }
        }
    }
}