简体   繁体   English

使用模拟创建Windows文件夹

[英]Creating Windows Folders using impersonation

I'm trying to create a folder using credentials of a limited admin account supplied by an encrypted .config file- right now my code is running under the assumption that the user has no access to these directories, so an unauthorizedexception is thrown, when given access the code otherwise works, but i can't do that as it would compromise our security. 我正在尝试使用由加密的.config文件提供的有限管理员帐户的凭据创建文件夹 - 现在我的代码在假设用户无法访问这些目录的情况下运行,因此在给定时会抛出unauthorizedexception访问代码否则有效,但我不能这样做,因为它会危及我们的安全。 I know how to get my username / password out of the encrypted file already, i'm just not sure as to what library or syntax i should use to impersonate; 我知道如何从加密文件中取出我的用户名/密码,我只是不确定我应该用什么库或语法来模仿; this is my code: 这是我的代码:

//set the cursor

string activeDir = "\\\\department\\shares\\users\\";

//create directory with userID as the folder name

string newPath = System.IO.Path.Combine(activeDir + userID);

System.IO.Directory.CreateDirectory(newPath);

so i need a way to supply credentials but i'm at a loss- i've been using System.DirectoryServices.AccountManagement and the pricipalcontext to supply a username/password for making changes to the active directory... do i need to use a similar library to make changes to the file system? 所以我需要一种方法来提供凭证,但我不知所措 - 我一直在使用System.DirectoryServices.AccountManagement和pricipalcontext提供用户名/密码来更改活动目录...我需要使用一个类似的库来更改文件系统? any help would be appreciated, thanks! 任何帮助将不胜感激,谢谢!

I think you could impersonate that user temporarily for the thread performing this action. 我认为您可以临时模拟执行此操作的线程的用户。 It seems that this only can be done with P/Invoke. 似乎这只能通过P / Invoke来完成。 Have a look at this example . 看看这个例子

using (var impersonation = new ImpersonatedUser(decryptedUser, decryptedDomain, decryptedPassword))
{
  Directory.CreateDirectory(newPath);
}

For the sake of completeness (if the link stops working some day), find the ImpersonatedUser class below (credits to Jon Cole ): 为了完整起见(如果某天链接停止工作),请找到下面的ImpersonatedUser类( Jon Cole的信用):

using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Security.Principal;

public class ImpersonatedUser : IDisposable
{
    IntPtr userHandle;

    WindowsImpersonationContext impersonationContext;

    public ImpersonatedUser(string user, string domain, string password)
    {
        userHandle = IntPtr.Zero;

        bool loggedOn = LogonUser(
            user,
            domain,
            password,
            LogonType.Interactive,
            LogonProvider.Default,
            out userHandle); 

        if (!loggedOn)
            throw new Win32Exception(Marshal.GetLastWin32Error());

        // Begin impersonating the user
        impersonationContext = WindowsIdentity.Impersonate(userHandle);
    } 

    public void Dispose()
    {
        if (userHandle != IntPtr.Zero)
        {
            CloseHandle(userHandle);

            userHandle = IntPtr.Zero;

            impersonationContext.Undo();
        }
    } 

    [DllImport("advapi32.dll", SetLastError = true)]
    static extern bool LogonUser(

        string lpszUsername,

        string lpszDomain,

        string lpszPassword,

        LogonType dwLogonType,

        LogonProvider dwLogonProvider,

        out IntPtr phToken

        );

    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool CloseHandle(IntPtr hHandle);

    enum LogonType : int
    {
        Interactive = 2,
        Network = 3,
        Batch = 4,
        Service = 5,
        NetworkCleartext = 8,
        NewCredentials = 9,
    }

    enum LogonProvider : int
    {
        Default = 0,
    }

}

Use Windows networking (WNet) functions. 使用Windows网络(WNet)功能。 They were supported by Windows 2000 and later. 它们得到Windows 2000及更高版本的支持。 Wrapper: 包装:

public class WNet
{
    public static void AddConnection(string resource, string username, string password)
    {
        NETRESOURCE nr = new NETRESOURCE();
        nr.RemoteName = resource;
        uint err = WNetAddConnection2W(ref nr, password, username, 0);
        if (err != 0)
            throw new RemoteDirectoryException(string.Format("WNetAddConnection2 failed with error: #{0}", err));
    }

    private struct NETRESOURCE
    {
        public uint Scope;
        public uint Type;
        public uint DisplayType;
        public uint Usage;
        public string LocalName;
        public string RemoteName;
        public string Comment;
        public string Provider;
    }

    [DllImport("mpr.dll", CharSet = CharSet.Unicode)]
    private extern static uint WNetAddConnection2W(ref NETRESOURCE lpNetResource, string lpPassword, string lpUsername, uint dwFlags);
}

Adding connection to resource and creating directory: 添加与资源的连接并创建目录:

string activeDir = "\\\\department\\shares\\users\\";
string username = "username";
string password = "password";

WNet.AddConnection(activeDir, username, password);

string newPath = System.IO.Path.Combine(activeDir, userID);
System.IO.Directory.CreateDirectory(newPath);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM