如何使用管理员凭据更改当前用户的文件夹权限?

时间:2013-09-02 20:34:17

标签: c# vbscript

好的,所以我一直在搜索,标题解释了我想要做的事情。 此外,在代码中硬编码管理员凭证也没有问题。

最初我在c#中写了一些代码,ALMOST解决了这个问题:

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);
        }
    }

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

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

提前致谢。

1 个答案:

答案 0 :(得分:3)

假冒将解决您的问题。当您在模拟上下文中执行代码时,将使用模拟用户的优先级执行该上下文中的逻辑。下面的类重写了web.config文件中的模拟配置值。您可以从app.config或任何来源修改它。

必需的配置

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

    假冒课程

     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
    }