0

好的,所以我一直在寻找一段时间,标题几乎解释了我想做的事情。此外,在代码中硬编码管理员凭据也没有问题。

最初我用 c# 写了一些代码,几乎解决了这个问题:

private void button2_Click(object sender, EventArgs e)
    {

        DirectoryInfo myDirectoryInfo = new DirectoryInfo(textBox1.Text);

        DirectorySecurity myDirectorySecurity = myDirectoryInfo.GetAccessControl();
        string User = System.Environment.UserDomainName + "\\" + comboBox1.SelectedItem.ToString();


        myDirectorySecurity.AddAccessRule(new FileSystemAccessRule(User, FileSystemRights.FullControl, InheritanceFlags.ContainerInherit, PropagationFlags.None, AccessControlType.Allow));

        //myDirectorySecurity.AddAccessRule(new FileSystemAccessRule(User, FileSystemRights.Write, InheritanceFlags.ContainerInherit, PropagationFlags.None, AccessControlType.Allow));

        myDirectoryInfo.SetAccessControl(myDirectorySecurity);
        MessageBox.Show("Permissions Altered Successfully" + User);

    }

如果我在我已经拥有权限的文件夹上使用,这很好用,但我需要的是一种使用管理员凭据向普通用户没有权限的文件夹授予权限的方法。

后来我尝试用vbscript写一些东西:

    strHomeFolder = "C:\test"
strUser = " DOMAIN\user"

Set WshShell = CreateObject("WScript.Shell")

WshShell.Run "%COMSPEC% /c Echo Y| cacls  "& strHomeFolder & " /e /c /g "& strUser &":F", 2, True

但我找不到传递管理员凭据的方法。所以最后我写了另一个代码来尝试完成它:

private void button1_Click(object sender, EventArgs e)
    {
        try
        {
            //string passwordPre = "PASSWORD";
            //char[] passwordChars = passwordPre.ToCharArray();
            //SecureString password = new SecureString();
            //foreach (char c in passwordChars)
            //{
            //    password.AppendChar(c);
            //}


            ProcessStartInfo p = new ProcessStartInfo(@"D:\\test.vbs");
            //p.UseShellExecute = false;
            //p.UserName = "username";
            //p.Domain = "DOMAIN";

            //p.Password = password;
            Process.Start(p);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

这次我只是尝试使用进程传递管理员凭据,但它生成了消息:指定的可执行文件不是此操作系统平台的有效应用程序。

那么,有什么方法可以用来传递凭据吗?(可以在 c# 或 vbscript 中)。

提前致谢。

4

1 回答 1

3

模拟将解决您的问题。当您在模拟上下文中执行代码时,放置在该上下文中的逻辑将以模拟用户的特权执行。下面的类从 web.config 文件中获取模拟配置值。您可以修改它从 app.config 或任何来源读取。

所需配置

  1. 用户名
  2. 密码
  3. 域名

模拟类

 public class Impersonator : IDisposable
    {
        #region Win32 Advanced API calls

        /// <summary>
        /// Logons the user.
        /// </summary>
        /// <param name="lpszUserName">Name of the LPSZ user.</param>
        /// <param name="lpszDomain">The LPSZ domain.</param>
        /// <param name="lpszPassword">The LPSZ password.</param>
        /// <param name="dwLogOnType">Type of the dw log on.</param>
        /// <param name="dwLogOnProvider">The dw log on provider.</param>
        /// <param name="phToken">The ph token.</param>
        /// <returns></returns>
        [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true,
            BestFitMapping = false, ThrowOnUnmappableChar = true)]
        private static extern int LogonUser(String lpszUserName,
                String lpszDomain,
                String lpszPassword,
                int dwLogOnType,
                int dwLogOnProvider,
                ref IntPtr phToken);

        /// <summary>
        /// Duplicates the token.
        /// </summary>
        /// <param name="hToken">The h token.</param>
        /// <param name="impersonationLevel">The impersonation level.</param>
        /// <param name="hNewToken">The h new token.</param>
        /// <returns></returns>
        [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true,
            BestFitMapping = false, ThrowOnUnmappableChar = true)]
        private static extern int DuplicateToken(IntPtr hToken,
                int impersonationLevel,
                ref IntPtr hNewToken);

        /// <summary>
        /// Reverts to self.
        /// </summary>
        /// <returns></returns>
        [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true,
            BestFitMapping = false, ThrowOnUnmappableChar = true)]
        private static extern bool RevertToSelf();


        /// <summary>
        /// Closes the handle.
        /// </summary>
        /// <param name="handle">The handle.</param>
        /// <returns></returns>
        [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true,
            BestFitMapping = false, ThrowOnUnmappableChar = true)]
        private static extern bool CloseHandle(IntPtr handle);

        #endregion

        #region Fields

        /// <summary>
        /// Field to hold the impersonation Context
        /// </summary>
        WindowsImpersonationContext impersonationContext;

        /// <summary>
        /// Track whether Dispose has been called.
        /// </summary>
        private bool disposed;

        #region Constants
        /// <summary>
        /// Logon32 Logon Interactive 
        /// </summary>
        public const int INTERACTIVE_NUMBER = 2;

        /// <summary>
        /// Logon32 Provider Default
        /// </summary>
        public const int DEFAULT_NUMBER = 0;

        /// <summary>
        /// Impersonating user name key
        /// </summary>
        public const string ImpersonatingUserNameKey = "ImpersonatingUserName";

        /// <summary>
        /// Impersonating user password key
        /// </summary>
        public const string ImpersonatingPasswordKey = "ImpersonatingUserPassword";

        /// <summary>
        /// Impersonating user domain key
        /// </summary>
        public const string ImpersonatingDomainNameKey = "ImpersonatingDomain";

        #endregion

        #endregion

        #region Construction/Destruction/Initialization

        /// <summary>
        /// Constructor of the impersonator
        /// </summary>
        public Impersonator()
        {
            if (!ImpersonateUser(ConfigurationManager.AppSettings[ImpersonatingUserNameKey],
                                    ConfigurationManager.AppSettings[ImpersonatingDomainNameKey],
                                    ConfigurationManager.AppSettings[ImpersonatingPasswordKey]))
            {
                //TODO: Log Exception
            }
        }

        #endregion

        #region Public Methods

        // Implement IDisposable.
        // Do not make this method virtual.
        // A derived class should not be able to override this method.
        public void Dispose()
        {
            Dispose(true);
            // This object will be cleaned up by the Dispose method.
            // Therefore, you should call GC.SupressFinalize to
            // take this object off the finalization queue
            // and prevent finalization code for this object
            // from executing a second time.
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// Impersonate User with the given user credentials
        /// </summary>
        /// <param name="userName">User Name</param>
        /// <param name="domain">Domain</param>
        /// <param name="password">Password</param>
        /// <returns>True if success, false otherwise</returns>
        private bool ImpersonateUser(String userName, String domain, String password)
        {
            WindowsIdentity tempWindowsIdentity;
            IntPtr token = IntPtr.Zero;
            IntPtr tokenDuplicate = IntPtr.Zero;

            if (RevertToSelf())
            {
                if (LogonUser(userName, domain, password, INTERACTIVE_NUMBER,
                        DEFAULT_NUMBER, ref token) != 0)
                {
                    if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
                    {
                        tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
                        impersonationContext = tempWindowsIdentity.Impersonate();
                        if (impersonationContext != null)
                        {
                            CloseHandle(token);
                            CloseHandle(tokenDuplicate);
                            return true;
                        }
                    }
                }
            }
            if (token != IntPtr.Zero)
                CloseHandle(token);
            if (tokenDuplicate != IntPtr.Zero)
                CloseHandle(tokenDuplicate);
            return false;
        }

        /// <summary>
        /// Undo impersonation
        /// </summary>
        private void StopImpersonation()
        {
            impersonationContext.Undo();
        }

        #endregion

        #region Protected Methods

        // Dispose(bool disposing) executes in two distinct scenarios.
        // If disposing equals true, the method has been called directly
        // or indirectly by a user's code. Managed and unmanaged resources
        // can be disposed.
        // If disposing equals false, the method has been called by the
        // runtime from inside the finalizer and you should not reference
        // other objects. Only unmanaged resources can be disposed.
        protected virtual void Dispose(bool disposing)
        {
            // Check to see if Dispose has already been called.
            if (!this.disposed)
            {
                // If disposing equals true, dispose all managed
                // and unmanaged resources.
                if (disposing)
                {
                    StopImpersonation();
                }

                // Note disposing has been done.
                disposed = true;
            }
        }

        #endregion
    }

如何调用方法

Using(Impersonator impersonator = new Impersonator())
{
  //Write the folder accessing logic here
}
于 2013-09-02T21:10:22.703 回答