শংসাপত্রগুলির সাথে একটি দূরবর্তী, অ-বিশ্বাসযোগ্য ডোমেন থেকে একটি ভাগ করা ফাইল (ইউএনসি) অ্যাক্সেস করা


151

আমরা একটি আকর্ষণীয় পরিস্থিতিতে চলে এসেছি যার সমাধানের প্রয়োজন, এবং আমার অনুসন্ধানগুলি শূন্য হয়েছে। তাই আমি এসও সম্প্রদায়ের কাছে সাহায্যের জন্য আবেদন করছি।

সমস্যাটি হ'ল: আমাদের এমন একটি ভাগ করা ফাইল যা প্রোগ্রামিংয়ে আমাদের ডোমেনে নেই এবং এটি দূরবর্তী ফাইল ভাগ করে নেওয়ার / ইউএনসির মাধ্যমে কোনও বিশ্বস্ত বহিরাগত ডোমেনের মধ্যে নেই। স্বাভাবিকভাবেই, আমাদের দূরবর্তী মেশিনে শংসাপত্র সরবরাহ করতে হবে।

সাধারণত, দুটি এই দুটি সমস্যার একটি সমাধান করতে পারে:

  1. একটি ড্রাইভ হিসাবে ফাইল ভাগ মানচিত্র এবং সেই সময় শংসাপত্র সরবরাহ। এটি সাধারণত NET USEকমান্ড বা Win32 ফাংশনগুলি ব্যবহার করে যা সদৃশ হয় NET USE
  2. ইউএনসি পাথ দিয়ে ফাইলটি অ্যাক্সেস করুন যেন দূরবর্তী কম্পিউটারটি ডোমেনে রয়েছে এবং নিশ্চিত করুন যে প্রোগ্রামটি যার অধীনে প্রোগ্রামটি চালিত হয় সেটিকে স্থানীয় ব্যবহারকারী হিসাবে রিমোট মেশিনে নকল (পাসওয়ার্ড সহ) প্রস্তুত করা হয়েছে। মূলত এই সত্যটি কাজে লাগান যে যখন ব্যবহারকারী কোনও ভাগ করা ফাইল অ্যাক্সেস করার চেষ্টা করে তখন উইন্ডোজ স্বয়ংক্রিয়ভাবে বর্তমান ব্যবহারকারীর শংসাপত্রগুলি সরবরাহ করে।
  3. রিমোট ফাইল শেয়ারিং ব্যবহার করবেন না। ফাইলটি স্থানান্তর করতে এফটিপি (বা অন্য কোনও উপায়) ব্যবহার করুন, স্থানীয়ভাবে এটিতে কাজ করুন, তারপরে আবার স্থানান্তর করুন।

বিভিন্ন এবং স্বতন্ত্র কারণে, আমাদের সুরক্ষা / নেটওয়ার্ক স্থপতিরা প্রথম দুটি পদ্ধতির প্রত্যাখ্যান করেছে। দ্বিতীয় পদ্ধতির স্পষ্টতই একটি সুরক্ষা গর্ত; দূরবর্তী কম্পিউটারে আপোস করা থাকলে, স্থানীয় কম্পিউটার এখন ঝুঁকির মধ্যে রয়েছে। প্রথম পন্থাটি অসন্তুষ্টিজনক কারণ নতুন মাউন্ট করা ড্রাইভ একটি কম্পিউটারে ফাইল অ্যাক্সেসের সময় স্থানীয় কম্পিউটারে অন্য প্রোগ্রামগুলিতে উপলব্ধ একটি শেয়ার্ড রিসোর্স। যদিও এই অস্থায়ী করা সম্ভব, তবুও এটি তাদের মতে একটি গর্ত।

তারা তৃতীয় বিকল্পের জন্য উন্মুক্ত, তবে দূরবর্তী নেটওয়ার্ক প্রশাসকরা এফটিপিএসের চেয়ে এসএফটিপিতে জোর দেয়, এবং ফ্যাটপিউব্রেকয়েস্ট কেবল এফটিপিএসকে সমর্থন করে। এসএফটিপি হ'ল ফায়ারওয়াল-বান্ধব বিকল্প এবং এই পদ্ধতির জন্য আমি ব্যবহার করতে পারি এমন বেশ কয়েকটি গ্রন্থাগার রয়েছে তবে আমি যদি পারি তবে আমার নির্ভরতা হ্রাস করতে পছন্দ করব।

রিমোট ফাইল শেয়ারিং ব্যবহারের জন্য আমি এমএসডিএন অনুসন্ধান করেছি, তবে দরকারী কিছু নিয়ে আসতে ব্যর্থ হয়েছি I

এবং তাই আমি জিজ্ঞাসা: অন্য উপায় আছে? আমি কি একটি সুপার-সিক্রেট উইন 32 ফাংশনটি মিস করেছি যা আমি যা করতে চাই? অথবা আমি বিকল্প 3 এর কিছু বৈকল্পিক অনুসরণ করতে হবে?


আমি এটি ছদ্মবেশী পদ্ধতির সাথে সমাধান করেছি, তবে এটি কোনও ডোমেনের বাইরে 2 মেশিনের মধ্যে রয়েছে। আমি জানি না যে এটি কোনও ডোমেন থেকে ডোমেনের বাইরে কম্পিউটারে কথা বলার সমস্যা সৃষ্টি করবে কিনা। stackoverflow.com/questions/17221476/...
Wolf5

উত্তর:


174

আপনার সমস্যা সমাধানের উপায় হ'ল WNetUseConnection নামক একটি Win32 API ব্যবহার করা ।
কোনও ড্রাইভের মানচিত্রের জন্য নয়, প্রমাণীকরণের সাথে ইউএনসি পথে সংযোগ করতে এই ফাংশনটি ব্যবহার করুন

এটি আপনাকে একই ডোমেনে না থাকলেও এবং এটির আলাদা আলাদা ব্যবহারকারীর নাম এবং পাসওয়ার্ড থাকলেও আপনাকে দূরবর্তী মেশিনে সংযোগ করার অনুমতি দেবে।

আপনি একবার WNetUseConnication ব্যবহার করার পরে আপনি কোনও ইউএনসি পাথের মাধ্যমে ফাইলটি অ্যাক্সেস করতে সক্ষম হবেন যেন আপনি একই ডোমেনে ছিলেন। সর্বোত্তম উপায়টি সম্ভবত শেয়ারগুলিতে নির্মিত প্রশাসনিক মাধ্যমে।
উদাহরণ: u computername \ c $ \ প্রোগ্রাম ফাইল \ ফোল্ডার \ file.txt

এখানে কিছু নমুনা সি # কোড যা WNetUseConnection ব্যবহার করে।
দ্রষ্টব্য, নেট রিসোর্সের জন্য, আপনার lpLocalName এবং lpProvider এর জন্য নাল পাস করা উচিত। DWType RESOURCETYPE_DISK হওয়া উচিত। LpRemoteName \\ ComputerName হওয়া উচিত।

using System;
using System.Runtime.InteropServices ;
using System.Threading;

namespace ExtremeMirror
{
    public class PinvokeWindowsNetworking
    {
        #region Consts
        const int RESOURCE_CONNECTED = 0x00000001;
        const int RESOURCE_GLOBALNET = 0x00000002;
        const int RESOURCE_REMEMBERED = 0x00000003;

        const int RESOURCETYPE_ANY = 0x00000000;
        const int RESOURCETYPE_DISK = 0x00000001;
        const int RESOURCETYPE_PRINT = 0x00000002;

        const int RESOURCEDISPLAYTYPE_GENERIC = 0x00000000;
        const int RESOURCEDISPLAYTYPE_DOMAIN = 0x00000001;
        const int RESOURCEDISPLAYTYPE_SERVER = 0x00000002;
        const int RESOURCEDISPLAYTYPE_SHARE = 0x00000003;
        const int RESOURCEDISPLAYTYPE_FILE = 0x00000004;
        const int RESOURCEDISPLAYTYPE_GROUP = 0x00000005;

        const int RESOURCEUSAGE_CONNECTABLE = 0x00000001;
        const int RESOURCEUSAGE_CONTAINER = 0x00000002;


        const int CONNECT_INTERACTIVE = 0x00000008;
        const int CONNECT_PROMPT = 0x00000010;
        const int CONNECT_REDIRECT = 0x00000080;
        const int CONNECT_UPDATE_PROFILE = 0x00000001;
        const int CONNECT_COMMANDLINE = 0x00000800;
        const int CONNECT_CMD_SAVECRED = 0x00001000;

        const int CONNECT_LOCALDRIVE = 0x00000100;
        #endregion

        #region Errors
        const int NO_ERROR = 0;

        const int ERROR_ACCESS_DENIED = 5;
        const int ERROR_ALREADY_ASSIGNED = 85;
        const int ERROR_BAD_DEVICE = 1200;
        const int ERROR_BAD_NET_NAME = 67;
        const int ERROR_BAD_PROVIDER = 1204;
        const int ERROR_CANCELLED = 1223;
        const int ERROR_EXTENDED_ERROR = 1208;
        const int ERROR_INVALID_ADDRESS = 487;
        const int ERROR_INVALID_PARAMETER = 87;
        const int ERROR_INVALID_PASSWORD = 1216;
        const int ERROR_MORE_DATA = 234;
        const int ERROR_NO_MORE_ITEMS = 259;
        const int ERROR_NO_NET_OR_BAD_PATH = 1203;
        const int ERROR_NO_NETWORK = 1222;

        const int ERROR_BAD_PROFILE = 1206;
        const int ERROR_CANNOT_OPEN_PROFILE = 1205;
        const int ERROR_DEVICE_IN_USE = 2404;
        const int ERROR_NOT_CONNECTED = 2250;
        const int ERROR_OPEN_FILES  = 2401;

        private struct ErrorClass 
        {
            public int num;
            public string message;
            public ErrorClass(int num, string message) 
            {
                this.num = num;
                this.message = message;
            }
        }


        // Created with excel formula:
        // ="new ErrorClass("&A1&", """&PROPER(SUBSTITUTE(MID(A1,7,LEN(A1)-6), "_", " "))&"""), "
        private static ErrorClass[] ERROR_LIST = new ErrorClass[] {
            new ErrorClass(ERROR_ACCESS_DENIED, "Error: Access Denied"), 
            new ErrorClass(ERROR_ALREADY_ASSIGNED, "Error: Already Assigned"), 
            new ErrorClass(ERROR_BAD_DEVICE, "Error: Bad Device"), 
            new ErrorClass(ERROR_BAD_NET_NAME, "Error: Bad Net Name"), 
            new ErrorClass(ERROR_BAD_PROVIDER, "Error: Bad Provider"), 
            new ErrorClass(ERROR_CANCELLED, "Error: Cancelled"), 
            new ErrorClass(ERROR_EXTENDED_ERROR, "Error: Extended Error"), 
            new ErrorClass(ERROR_INVALID_ADDRESS, "Error: Invalid Address"), 
            new ErrorClass(ERROR_INVALID_PARAMETER, "Error: Invalid Parameter"), 
            new ErrorClass(ERROR_INVALID_PASSWORD, "Error: Invalid Password"), 
            new ErrorClass(ERROR_MORE_DATA, "Error: More Data"), 
            new ErrorClass(ERROR_NO_MORE_ITEMS, "Error: No More Items"), 
            new ErrorClass(ERROR_NO_NET_OR_BAD_PATH, "Error: No Net Or Bad Path"), 
            new ErrorClass(ERROR_NO_NETWORK, "Error: No Network"), 
            new ErrorClass(ERROR_BAD_PROFILE, "Error: Bad Profile"), 
            new ErrorClass(ERROR_CANNOT_OPEN_PROFILE, "Error: Cannot Open Profile"), 
            new ErrorClass(ERROR_DEVICE_IN_USE, "Error: Device In Use"), 
            new ErrorClass(ERROR_EXTENDED_ERROR, "Error: Extended Error"), 
            new ErrorClass(ERROR_NOT_CONNECTED, "Error: Not Connected"), 
            new ErrorClass(ERROR_OPEN_FILES, "Error: Open Files"), 
        };

        private static string getErrorForNumber(int errNum) 
        {
            foreach (ErrorClass er in ERROR_LIST) 
            {
                if (er.num == errNum) return er.message;
            }
            return "Error: Unknown, " + errNum;
        }
        #endregion

        [DllImport("Mpr.dll")] private static extern int WNetUseConnection(
            IntPtr hwndOwner,
            NETRESOURCE lpNetResource,
            string lpPassword,
            string lpUserID,
            int dwFlags,
            string lpAccessName,
            string lpBufferSize,
            string lpResult
        );

        [DllImport("Mpr.dll")] private static extern int WNetCancelConnection2(
            string lpName,
            int dwFlags,
            bool fForce
        );

        [StructLayout(LayoutKind.Sequential)] private class NETRESOURCE
        { 
            public int dwScope = 0;
            public int dwType = 0;
            public int dwDisplayType = 0;
            public int dwUsage = 0;
            public string lpLocalName = "";
            public string lpRemoteName = "";
            public string lpComment = "";
            public string lpProvider = "";
        }


        public static string connectToRemote(string remoteUNC, string username, string password) 
        {
            return connectToRemote(remoteUNC, username, password, false);
        }

        public static string connectToRemote(string remoteUNC, string username, string password, bool promptUser) 
        {
            NETRESOURCE nr = new NETRESOURCE();
            nr.dwType = RESOURCETYPE_DISK;
            nr.lpRemoteName = remoteUNC;
            //          nr.lpLocalName = "F:";

            int ret;
            if (promptUser) 
                ret = WNetUseConnection(IntPtr.Zero, nr, "", "", CONNECT_INTERACTIVE | CONNECT_PROMPT, null, null, null);
            else 
                ret = WNetUseConnection(IntPtr.Zero, nr, password, username, 0, null, null, null);

            if (ret == NO_ERROR) return null;
            return getErrorForNumber(ret);
        }

        public static string disconnectRemote(string remoteUNC) 
        {
            int ret = WNetCancelConnection2(remoteUNC, CONNECT_UPDATE_PROFILE, false);
            if (ret == NO_ERROR) return null;
            return getErrorForNumber(ret);
        }
    }
}

বর্তমান শংসাপত্রগুলি ব্যবহার করে, যেমন, ব্যবহারকারীর নাম এবং পাসওয়ার্ড না দিয়ে স্পষ্টভাবে কোনও নেটওয়ার্ক মেশিনে সংযোগগুলি খুলতে / বন্ধ করতে এই জাতীয় ফাংশন ব্যবহার করার কোনও উপায় আছে কি? আমি একটি ফাইল শেয়ার অ্যাক্সেস করার পরে একটি সংযোগ বন্ধ করতে বিশেষভাবে আগ্রহী।
ফ্লিপডব্যাট

সংযোগের জন্য নয়, যদি না কম্পিউটারে নিজেই একটি ব্যবহারকারীর নাম বা পাসওয়ার্ড না থাকে। আপনি এটি করতে পারেন তা সংযোগ বিচ্ছিন্ন করার জন্য। আপনি এটি পরিবর্তে কমান্ড লাইনের মাধ্যমেও করতে পারেন।
ব্রায়ান আর বন্ডি

1
হাই ব্রায়ান আপনি যে শংসাপত্রের সাথে লিঙ্ক করেছেন তা বর্তমান পরিচয়পত্রগুলি ব্যবহার করার জন্য আপনি ব্যবহারকারীর নাম এবং পাসওয়ার্ডের জন্য NULL পাস করতে পারেন। এটি কাজ করে কিনা তা দেখার জন্য আমি কিছু পরীক্ষা করব।
ফ্লিপডব্যাট

ব্যবহারকারীর নাম / পাসওয়ার্ডের জন্য নাল পাস করা আমাকে সংযোগ করতে দেয় তবে আমি কীভাবে প্রমাণ করতে পারি যে আমি সংযোগ বিচ্ছিন্ন করেছি? সার্ভারে এমন কিছু আছে যা আমি দেখতে পারি? সার্ভার 2003-এ, আমি সেশনগুলি দেখতে পারি, তবে আমার অ্যাপ্লিকেশনটি এই এপিআইগুলি ব্যবহার না করার সাথে সাথে বর্তমান সেশনগুলির তালিকা আপডেট হয়।
ফ্লিপডবট

সাথে সংযোগগুলি কি WNetUseConnectionকল করে ম্যানুয়ালি বন্ধ করা উচিত WNetCancelConnection2? বা একটি অলস সময়সীমা (বা অন্য কোনও প্রক্রিয়া) আছে এবং আমাদের বিরক্ত করার দরকার নেই?
w128

123

দ্রুত সমাধানের সন্ধানকারী লোকদের জন্য, আপনি NetworkShareAccesserসম্প্রতি লিখেছেন ব্যবহার করতে পারেন ( এই উত্তরের ভিত্তিতে (অনেক ধন্যবাদ!)):

ব্যবহার:

using (NetworkShareAccesser.Access(REMOTE_COMPUTER_NAME, DOMAIN, USER_NAME, PASSWORD))
{
    File.Copy(@"C:\Some\File\To\copy.txt", @"\\REMOTE-COMPUTER\My\Shared\Target\file.txt");
}

সতর্কতা: দয়া করে একেবারে নিশ্চিত, যে Disposeএর NetworkShareAccesser, (এমনকি যদি আপনি ক্র্যাশ অ্যাপ্লিকেশান!) বলা হয় অন্যথায় একটি খোলা সংযোগ Windows এ থাকবে। cmdপ্রম্পটটি খোলার মাধ্যমে আপনি সমস্ত উন্মুক্ত সংযোগগুলি দেখতে পাবেন এবং প্রবেশ করুন net use

কোড:

/// <summary>
/// Provides access to a network share.
/// </summary>
public class NetworkShareAccesser : IDisposable
{
    private string _remoteUncName;
    private string _remoteComputerName;

    public string RemoteComputerName
    {
        get
        {
            return this._remoteComputerName;
        }
        set
        {
            this._remoteComputerName = value;
            this._remoteUncName = @"\\" + this._remoteComputerName;
        }
    }

    public string UserName
    {
        get;
        set;
    }
    public string Password
    {
        get;
        set;
    }

    #region Consts

    private const int RESOURCE_CONNECTED = 0x00000001;
    private const int RESOURCE_GLOBALNET = 0x00000002;
    private const int RESOURCE_REMEMBERED = 0x00000003;

    private const int RESOURCETYPE_ANY = 0x00000000;
    private const int RESOURCETYPE_DISK = 0x00000001;
    private const int RESOURCETYPE_PRINT = 0x00000002;

    private const int RESOURCEDISPLAYTYPE_GENERIC = 0x00000000;
    private const int RESOURCEDISPLAYTYPE_DOMAIN = 0x00000001;
    private const int RESOURCEDISPLAYTYPE_SERVER = 0x00000002;
    private const int RESOURCEDISPLAYTYPE_SHARE = 0x00000003;
    private const int RESOURCEDISPLAYTYPE_FILE = 0x00000004;
    private const int RESOURCEDISPLAYTYPE_GROUP = 0x00000005;

    private const int RESOURCEUSAGE_CONNECTABLE = 0x00000001;
    private const int RESOURCEUSAGE_CONTAINER = 0x00000002;


    private const int CONNECT_INTERACTIVE = 0x00000008;
    private const int CONNECT_PROMPT = 0x00000010;
    private const int CONNECT_REDIRECT = 0x00000080;
    private const int CONNECT_UPDATE_PROFILE = 0x00000001;
    private const int CONNECT_COMMANDLINE = 0x00000800;
    private const int CONNECT_CMD_SAVECRED = 0x00001000;

    private const int CONNECT_LOCALDRIVE = 0x00000100;

    #endregion

    #region Errors

    private const int NO_ERROR = 0;

    private const int ERROR_ACCESS_DENIED = 5;
    private const int ERROR_ALREADY_ASSIGNED = 85;
    private const int ERROR_BAD_DEVICE = 1200;
    private const int ERROR_BAD_NET_NAME = 67;
    private const int ERROR_BAD_PROVIDER = 1204;
    private const int ERROR_CANCELLED = 1223;
    private const int ERROR_EXTENDED_ERROR = 1208;
    private const int ERROR_INVALID_ADDRESS = 487;
    private const int ERROR_INVALID_PARAMETER = 87;
    private const int ERROR_INVALID_PASSWORD = 1216;
    private const int ERROR_MORE_DATA = 234;
    private const int ERROR_NO_MORE_ITEMS = 259;
    private const int ERROR_NO_NET_OR_BAD_PATH = 1203;
    private const int ERROR_NO_NETWORK = 1222;

    private const int ERROR_BAD_PROFILE = 1206;
    private const int ERROR_CANNOT_OPEN_PROFILE = 1205;
    private const int ERROR_DEVICE_IN_USE = 2404;
    private const int ERROR_NOT_CONNECTED = 2250;
    private const int ERROR_OPEN_FILES = 2401;

    #endregion

    #region PInvoke Signatures

    [DllImport("Mpr.dll")]
    private static extern int WNetUseConnection(
        IntPtr hwndOwner,
        NETRESOURCE lpNetResource,
        string lpPassword,
        string lpUserID,
        int dwFlags,
        string lpAccessName,
        string lpBufferSize,
        string lpResult
        );

    [DllImport("Mpr.dll")]
    private static extern int WNetCancelConnection2(
        string lpName,
        int dwFlags,
        bool fForce
        );

    [StructLayout(LayoutKind.Sequential)]
    private class NETRESOURCE
    {
        public int dwScope = 0;
        public int dwType = 0;
        public int dwDisplayType = 0;
        public int dwUsage = 0;
        public string lpLocalName = "";
        public string lpRemoteName = "";
        public string lpComment = "";
        public string lpProvider = "";
    }

    #endregion

    /// <summary>
    /// Creates a NetworkShareAccesser for the given computer name. The user will be promted to enter credentials
    /// </summary>
    /// <param name="remoteComputerName"></param>
    /// <returns></returns>
    public static NetworkShareAccesser Access(string remoteComputerName)
    {
        return new NetworkShareAccesser(remoteComputerName);
    }

    /// <summary>
    /// Creates a NetworkShareAccesser for the given computer name using the given domain/computer name, username and password
    /// </summary>
    /// <param name="remoteComputerName"></param>
    /// <param name="domainOrComuterName"></param>
    /// <param name="userName"></param>
    /// <param name="password"></param>
    public static NetworkShareAccesser Access(string remoteComputerName, string domainOrComuterName, string userName, string password)
    {
        return new NetworkShareAccesser(remoteComputerName,
                                        domainOrComuterName + @"\" + userName,
                                        password);
    }

    /// <summary>
    /// Creates a NetworkShareAccesser for the given computer name using the given username (format: domainOrComputername\Username) and password
    /// </summary>
    /// <param name="remoteComputerName"></param>
    /// <param name="userName"></param>
    /// <param name="password"></param>
    public static NetworkShareAccesser Access(string remoteComputerName, string userName, string password)
    {
        return new NetworkShareAccesser(remoteComputerName, 
                                        userName,
                                        password);
    }

    private NetworkShareAccesser(string remoteComputerName)
    {
        RemoteComputerName = remoteComputerName;               

        this.ConnectToShare(this._remoteUncName, null, null, true);
    }

    private NetworkShareAccesser(string remoteComputerName, string userName, string password)
    {
        RemoteComputerName = remoteComputerName;
        UserName = userName;
        Password = password;

        this.ConnectToShare(this._remoteUncName, this.UserName, this.Password, false);
    }

    private void ConnectToShare(string remoteUnc, string username, string password, bool promptUser)
    {
        NETRESOURCE nr = new NETRESOURCE
        {
            dwType = RESOURCETYPE_DISK,
            lpRemoteName = remoteUnc
        };

        int result;
        if (promptUser)
        {
            result = WNetUseConnection(IntPtr.Zero, nr, "", "", CONNECT_INTERACTIVE | CONNECT_PROMPT, null, null, null);
        }
        else
        {
            result = WNetUseConnection(IntPtr.Zero, nr, password, username, 0, null, null, null);
        }

        if (result != NO_ERROR)
        {
            throw new Win32Exception(result);
        }
    }

    private void DisconnectFromShare(string remoteUnc)
    {
        int result = WNetCancelConnection2(remoteUnc, CONNECT_UPDATE_PROFILE, false);
        if (result != NO_ERROR)
        {
            throw new Win32Exception(result);
        }
    }

    /// <summary>
    /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
    /// </summary>
    /// <filterpriority>2</filterpriority>
    public void Dispose()
    {
        this.DisconnectFromShare(this._remoteUncName);
    }
}

2
আপনার কাছে প্রয়োজন using System.Runtime.InteropServices;এবং using System.ComponentModel;জন্য DllImportএবংWin32Exception
Kᴀτᴢ

এই সমাধানটি আমার দীর্ঘ দিনের অনুসন্ধান বন্ধ করে দিয়েছে। ধন্যবাদ !!! প্রয়োজনীয় হিসাবে বেশ ভাল কাজ করে।
ভেঙ্কট

1
আমি রিমোট মেশিনে স্থানীয় ব্যবহারকারীর অ্যাকাউন্টের সাথে আপনার সমাধানটি ব্যবহার করার চেষ্টা করছি, তবে আমি অ্যাক্সেস অস্বীকার করে ত্রুটি পেতে থাকি। আপনার সমাধানটি কেবল নেটওয়ার্ক অ্যাকাউন্টগুলির জন্যই কাজ করবে?
এম

1
অ্যাকাউন্টটি রিমোট মেশিনে বিদ্যমান, তবে এটি কোনও নেটওয়ার্ক অ্যাকাউন্ট নয়। এটি একটি স্থানীয় মেশিন অ্যাকাউন্ট। আমি মেশিনটির নামে ডোমেন সেট করার চেষ্টা করেছি। আমি ভাগ করা ফোল্ডারে স্থানীয় ব্যবহারকারীর অ্যাকাউন্টে সম্পূর্ণ অনুমতিও দিয়েছি, তবে আমি অ্যাক্সেস বঞ্চিত হয়েছি। কেন এমনটি হতে পারে সে সম্পর্কে কোনও ধারণা? ধন্যবাদ.
এম

2
দ্রষ্টব্য: অবজেক্টটি নিষ্পত্তি করা সিস্টেম থেকে শংসাপত্রগুলি মুছে ফেলবে না বলে মনে হচ্ছে (উইন্ডোজ 10); সংযোগটি "বাতিল" হয়ে যাওয়ার পরে আমি দূরবর্তী কম্পিউটারে ফাইলগুলি অ্যাক্সেস করতে সক্ষম হয়েছি। আমার ব্যবহারকারীর অ্যাকাউন্টে পুনরায় লগইন করা বা আমার কম্পিউটার পুনরায় চালু করা এই অভ্যন্তরীণ ক্যাশেটিকে সাফ করে বলে মনে হচ্ছে।
টিম কুপার

16

আফাইক, কোনও সার্ভারের শংসাপত্র স্থাপনের জন্য আপনাকে ড্রাইভ লেটারের ইউএনসি পথটি মানচিত্রের প্রয়োজন হবে না । আমি নিয়মিত ব্যাচের স্ক্রিপ্টগুলি ব্যবহার করতাম:

net use \\myserver /user:username password

:: do something with \\myserver\the\file\i\want.xml

net use /delete \\my.server.com

তবে, আপনার প্রোগ্রাম হিসাবে একই অ্যাকাউন্টে চলমান যে কোনও প্রোগ্রাম এখনও অ্যাক্সেসযুক্ত সমস্ত কিছুতে username:passwordঅ্যাক্সেস করতে সক্ষম হবে। একটি সম্ভাব্য সমাধান হ'ল আপনার প্রোগ্রামটিকে তার নিজস্ব স্থানীয় ব্যবহারকারীর অ্যাকাউন্টে বিচ্ছিন্ন করা (ইউএনসি অ্যাক্সেস যে অ্যাকাউন্টে বলা হয় তার স্থানীয় হয় NET USE)।

দ্রষ্টব্য: এসএমবি অ্যাক্রস ডোমেনগুলি ব্যবহার করা প্রযুক্তি, আইএমওর পক্ষে বেশ ভাল ব্যবহার নয়। সুরক্ষাটি যদি গুরুত্বপূর্ণ হয় তবে এসএমবিতে এনক্রিপশনের অভাবের বিষয়টি নিজে থেকে কিছুটা ছিটে।


যদি আপনি UNC অ্যাক্সেসটি কেবলমাত্র যে অ্যাকাউন্টটি ডেকে থাকে কেবল সেটির জন্য উপলব্ধ থাকে সে সম্পর্কে আপনি যদি সঠিক হন তবে NET USEএটি একটি কার্যকর পন্থা হতে পারে। আপনি কি নিশ্চিত যে আমাদের একটি স্থানীয় অ্যাকাউন্ট ব্যবহার করা উচিত? NET USEকলটি সেই মেশিনে কল হবে না যেখানে এটি কল করা হয়েছিল? আপনি আমাকে একটি ভাল গবেষণার পথ দিয়েছেন
র্যান্ডলফো

আফাইক, এবং আমি ভুল হতে পারি, ইউএনসির অ্যাক্সেস কেবলমাত্র নির্দিষ্ট সিকিউরিটি অধ্যক্ষকে (এসএএম অ্যাকাউন্ট, যাই হোক না কেন) পাওয়া যাবে যার অধীনে নেট ইউএসইতে কল করা হয়েছিল। আপনি পাথটি মানচিত্রের জন্য রানএ ব্যবহার করে এবং এটি অন্য অ্যাকাউন্ট থেকে অ্যাক্সেস করার চেষ্টা করে এটি যাচাই করতে পারেন।
জ্যাকব

আমার ক্ষেত্রে, আমাকে নেট ব্যবহার করতে হয়েছিল \\ মাইজার সার্ভার / ইউজার: ব্যবহারকারীর নাম @ ডোমেন পাসওয়ার্ড ব্যবহারকারী হিসাবে অন্য কোনও ডোমেনে রয়েছে।
স্টারকব

4

WNetUseConnication এর পরিবর্তে আমি নেটউসএড যুক্ত করার পরামর্শ দিই । WNetUseConnication একটি লিগ্যাসি ফাংশন যা ডাব্লুনেটউসকনেকশন 2 এবং ডাব্লুনেট ইউজেকশন 3 দ্বারা চালিত হয়েছে তবে উইন্ডোজ এক্সপ্লোরারগুলিতে দৃশ্যমান এমন একটি নেটওয়ার্ক ডিভাইস তৈরি করে এই সমস্ত ফাংশন। রিমোট কম্পিউটারে প্রমাণীকরণের জন্য ডস প্রম্পটে নেট ইউজিং কল করার সমতুল্য নেট ইউএসএডিএড।

আপনি যদি নেটউসএডএড কল করেন তবে ডিরেক্টরিতে অ্যাক্সেসের পরবর্তী প্রচেষ্টা সফল হওয়া উচিত।


1
@ অ্যাডাম রবিনসন: এটি সত্য নয়। এই জাতীয় কোনও WNetUseConnication2 বা WNetUseConnication3 নেই। আমার মনে হয় আপনি WNetAddConnication2 এবং WnetAddConnication3 দ্বারা ডুবে যাওয়া WNetAddConnication সম্পর্কে ভাবনা ভাবছেন। এছাড়াও আপনি এটি সম্পর্কে যে তথ্য দিয়েছেন তা সত্য নয়।
ব্রায়ান আর বন্ডি

WNetUseConnication ডাব্লুনেটএডডকনেকশন 3 এর মতো, তবে এটি ম্যাপযুক্ত লোকাল ড্রাইভ তৈরির একটি abilityচ্ছিক ক্ষমতাও রয়েছে। যা আপনাকে ব্যবহার করতে হবে না।
ব্রায়ান আর। বন্ডি

@ ব্রায়ানআর.বন্ডি তাদের আসলেই রয়েছে, কেবল # # হিসাবে প্রয়োগ করা হয়নি। সূত্র: ডকস.মাইক্রোসফট.ডেএইডক / উইন্ডস / উইন্ডো 32 / api / lmuse/… উদ্ধৃতি: "আপনি স্থানীয় ডিভাইসটিকে একটি নেটওয়ার্ক রিসোর্সে ডাইরেক্ট করতে ডাব্লুনেটএডডকনেকশন 2 এবং ডাব্লুনেটএডডকনেকশন 3 ফাংশনও ব্যবহার করতে পারেন।"
টমাস উইলিয়ামস

4

যদিও আমি নিজেকে জানি না, আমি অবশ্যই আশা করি যে # 2 টি ভুল আছে ... আমি ভাবতে চাই যে উইন্ডোজ স্বয়ংক্রিয়ভাবে কোনও লগিনের তথ্য (আমার পাসওয়ার্ডের কমপক্ষে!) কোনও মেশিনে দেবে না , আমার বিশ্বাসের অংশ নয় এমন একটিকে ছেড়ে দিন।

নির্বিশেষে, আপনি ছদ্মবেশকরণ আর্কিটেকচার অন্বেষণ করেছেন? আপনার কোডটি এর অনুরূপ দেখতে চলেছে:

using (System.Security.Principal.WindowsImpersonationContext context = System.Security.Principal.WindowsIdentity.Impersonate(token))
{
    // Do network operations here

    context.Undo();
}

এক্ষেত্রে tokenভেরিয়েবলটি একটি ইন্টারপ্রেটার। এই ভেরিয়েবলের মান পেতে হলে আপনাকে নিয়ন্ত্রণহীন লগনউজার উইন্ডোজ এপিআই ফাংশনটি কল করতে হবে। পিনভোক.নেটে একটি দ্রুত ভ্রমণ আমাদের নীচের স্বাক্ষর দেয়:

[System.Runtime.InteropServices.DllImport("advapi32.dll", SetLastError = true)]
public static extern bool LogonUser(
    string lpszUsername,
    string lpszDomain,
    string lpszPassword,
    int dwLogonType,
    int dwLogonProvider,
    out IntPtr phToken
);

ব্যবহারকারীর নাম, ডোমেন এবং পাসওয়ার্ড মোটামুটি সুস্পষ্ট মনে হবে। আপনার প্রয়োজন অনুসারে সবচেয়ে উপযুক্ত মান নির্ধারণ করতে dwLogonType এবং dwLogonProvider এ যে বিভিন্ন মান দেওয়া যেতে পারে তা দেখুন।

এই কোডটি পরীক্ষা করা হয়নি, কারণ এখানে আমার দ্বিতীয় ডোমেন নেই যেখানে আমি যাচাই করতে পারি, তবে আশা করা যায় এটি আপনাকে সঠিক পথে রাখবে।


7
আপনি যখন অবিশ্বস্ত ডোমেন থেকে লগইন আইডি ব্যবহার করার চেষ্টা করছেন তখন ছদ্মবেশটি কাজ করবে না। ব্যবহারকারী আইডি স্থানীয়ভাবে লগ ইন করতে সক্ষম হতে হবে।
আমেরিকার হরিণবিশেষ

হ্যাঁ, আমরা এই রুটটি চেষ্টা করেছি, এটি শেষ হয়েছে @ মুস বলেছেন: ডোমেনটি অবিশ্বস্ত এবং সুতরাং ছদ্মবেশ কাজ করবে না।
রেন্ডলফো

হ্যাঁ, আমি একবার সেই মন্তব্যে দেখেছি এজন্যই আমি নেটউসএডএড ব্যবহার করে উত্তরটি পোস্ট করেছি (এটি এবং ডাব্লুনেটসেকশন এবং ডব্লিউনেটএডকনেকশন ফাংশনগুলির মধ্যে নেট পার্থক্য যে উইন্ডোজ এক্সপ্লোরারে সংযোগটি দৃশ্যমান করে না)।
অ্যাডাম রবিনসন

ছদ্মবেশটি একই ডোমেনে কাজ করে না, আমার পরীক্ষাগুলিতে এটি আমাকে প্রশাসক অ্যাকাউন্ট (উভয় মেশিনের অ্যাডমিন) সহ ভাগ করা ফোল্ডারে কোনও ফাইল পড়ার চেষ্টা করার সাথে সাথে অ্যাক্সেস অস্বীকারের সাথে সাড়া দেয়। সুতরাং, আমি মনে করি এটি সঠিক পদ্ধতির নয়।
lidermin

4

এখানে একটি সর্বনিম্ন পোকি ক্লাস ডাব্লু / সমস্ত ক্রাফ্ট সরানো হয়েছে

using System;
using System.ComponentModel;
using System.Runtime.InteropServices;

public class UncShareWithCredentials : IDisposable
{
    private string _uncShare;

    public UncShareWithCredentials(string uncShare, string userName, string password)
    {
        var nr = new Native.NETRESOURCE
        {
            dwType = Native.RESOURCETYPE_DISK,
            lpRemoteName = uncShare
        };

        int result = Native.WNetUseConnection(IntPtr.Zero, nr, password, userName, 0, null, null, null);
        if (result != Native.NO_ERROR)
        {
            throw new Win32Exception(result);
        }
        _uncShare = uncShare;
    }

    public void Dispose()
    {
        if (!string.IsNullOrEmpty(_uncShare))
        {
            Native.WNetCancelConnection2(_uncShare, Native.CONNECT_UPDATE_PROFILE, false);
            _uncShare = null;
        }
    }

    private class Native
    {
        public const int RESOURCETYPE_DISK = 0x00000001;
        public const int CONNECT_UPDATE_PROFILE = 0x00000001;
        public const int NO_ERROR = 0;

        [DllImport("mpr.dll")]
        public static extern int WNetUseConnection(IntPtr hwndOwner, NETRESOURCE lpNetResource, string lpPassword, string lpUserID,
            int dwFlags, string lpAccessName, string lpBufferSize, string lpResult);

        [DllImport("mpr.dll")]
        public static extern int WNetCancelConnection2(string lpName, int dwFlags, bool fForce);

        [StructLayout(LayoutKind.Sequential)]
        public class NETRESOURCE
        {
            public int dwScope;
            public int dwType;
            public int dwDisplayType;
            public int dwUsage;
            public string lpLocalName;
            public string lpRemoteName;
            public string lpComment;
            public string lpProvider;
        }
    }
}

আপনি সরাসরি \\server\share\folderডাব্লু / ব্যবহার করতে পারেন WNetUseConnection, \\serverকেবল এটি আগে ভাগ করার জন্য স্ট্রিপ করতে হবে না ।


2

বেশিরভাগ এসএফটিপি সার্ভারগুলি এসসিপিকে সমর্থন করে যা এর জন্য লাইব্রেরিগুলি খুঁজে পাওয়া অনেক সহজ হতে পারে। এমনকি আপনি শুধু আপনার কোড থেকে একটি বিদ্যমান ক্লায়েন্ট বলতে পেরেছিলাম pscp মত সঙ্গে অন্তর্ভুক্ত পুটিং

আপনি যে ধরণের ফাইলটির সাথে কাজ করছেন তা যদি কোনও পাঠ্য বা এক্সএমএল ফাইলের মতো সাধারণ কিছু হয় তবে আপনি নিজের ক্লায়েন্ট / সার্ভার বাস্তবায়ন লিখতে পারেন। নেট রিমোটিং বা ওয়েব পরিষেবাদির মতো কিছু ব্যবহার করে ফাইলটি পরিচালনা করতে।



1

আমি আমার vb.net কোড ব্রায়ান রেফারেন্স উপর ভিত্তি করে সংযুক্ত

Imports System.ComponentModel

Imports System.Runtime.InteropServices

Public Class PinvokeWindowsNetworking

Const NO_ERROR As Integer = 0



Private Structure ErrorClass

    Public num As Integer

    Public message As String



    Public Sub New(ByVal num As Integer, ByVal message As String)

        Me.num = num

        Me.message = message

    End Sub

End Structure



Private Shared ERROR_LIST As ErrorClass() = New ErrorClass() {

    New ErrorClass(5, "Error: Access Denied"),

    New ErrorClass(85, "Error: Already Assigned"),

    New ErrorClass(1200, "Error: Bad Device"),

    New ErrorClass(67, "Error: Bad Net Name"),

    New ErrorClass(1204, "Error: Bad Provider"),

    New ErrorClass(1223, "Error: Cancelled"),

    New ErrorClass(1208, "Error: Extended Error"),

    New ErrorClass(487, "Error: Invalid Address"),

    New ErrorClass(87, "Error: Invalid Parameter"),

    New ErrorClass(1216, "Error: Invalid Password"),

    New ErrorClass(234, "Error: More Data"),

    New ErrorClass(259, "Error: No More Items"),

    New ErrorClass(1203, "Error: No Net Or Bad Path"),

    New ErrorClass(1222, "Error: No Network"),

    New ErrorClass(1206, "Error: Bad Profile"),

    New ErrorClass(1205, "Error: Cannot Open Profile"),

    New ErrorClass(2404, "Error: Device In Use"),

    New ErrorClass(2250, "Error: Not Connected"),

    New ErrorClass(2401, "Error: Open Files")}



Private Shared Function getErrorForNumber(ByVal errNum As Integer) As String

    For Each er As ErrorClass In ERROR_LIST

        If er.num = errNum Then Return er.message

    Next



    Try

        Throw New Win32Exception(errNum)

    Catch ex As Exception

        Return "Error: Unknown, " & errNum & " " & ex.Message

    End Try



    Return "Error: Unknown, " & errNum

End Function



<DllImport("Mpr.dll")>

Private Shared Function WNetUseConnection(ByVal hwndOwner As IntPtr, ByVal lpNetResource As NETRESOURCE, ByVal lpPassword As String, ByVal lpUserID As String, ByVal dwFlags As Integer, ByVal lpAccessName As String, ByVal lpBufferSize As String, ByVal lpResult As String) As Integer

End Function



<DllImport("Mpr.dll")>

Private Shared Function WNetCancelConnection2(ByVal lpName As String, ByVal dwFlags As Integer, ByVal fForce As Boolean) As Integer

End Function



<StructLayout(LayoutKind.Sequential)>

Private Class NETRESOURCE

    Public dwScope As Integer = 0

    Public dwType As Integer = 0

    Public dwDisplayType As Integer = 0

    Public dwUsage As Integer = 0

    Public lpLocalName As String = ""

    Public lpRemoteName As String = ""

    Public lpComment As String = ""

    Public lpProvider As String = ""

End Class



Public Shared Function connectToRemote(ByVal remoteUNC As String, ByVal username As String, ByVal password As String) As String

    Return connectToRemote(remoteUNC, username, password, False)

End Function



Public Shared Function connectToRemote(ByVal remoteUNC As String, ByVal username As String, ByVal password As String, ByVal promptUser As Boolean) As String

    Dim nr As NETRESOURCE = New NETRESOURCE()

    nr.dwType = ResourceTypes.Disk

    nr.lpRemoteName = remoteUNC

    Dim ret As Integer



    If promptUser Then

        ret = WNetUseConnection(IntPtr.Zero, nr, "", "", Connects.Interactive Or Connects.Prompt, Nothing, Nothing, Nothing)

    Else

        ret = WNetUseConnection(IntPtr.Zero, nr, password, username, 0, Nothing, Nothing, Nothing)

    End If



    If ret = NO_ERROR Then Return Nothing

    Return getErrorForNumber(ret)

End Function



Public Shared Function disconnectRemote(ByVal remoteUNC As String) As String

    Dim ret As Integer = WNetCancelConnection2(remoteUNC, Connects.UpdateProfile, False)

    If ret = NO_ERROR Then Return Nothing

    Return getErrorForNumber(ret)

End Function


Enum Resources As Integer

    Connected = &H1

    GlobalNet = &H2

    Remembered = &H3

End Enum


Enum ResourceTypes As Integer

    Any = &H0

    Disk = &H1

    Print = &H2

End Enum


Enum ResourceDisplayTypes As Integer

    Generic = &H0

    Domain = &H1

    Server = &H2

    Share = &H3

    File = &H4

    Group = &H5

End Enum


Enum ResourceUsages As Integer

    Connectable = &H1

    Container = &H2

End Enum


Enum Connects As Integer

    Interactive = &H8

    Prompt = &H10

    Redirect = &H80

    UpdateProfile = &H1

    CommandLine = &H800

    CmdSaveCred = &H1000

    LocalDrive = &H100

End Enum


End Class

এটি কিভাবে ব্যবহার করতে

Dim login = PinvokeWindowsNetworking.connectToRemote("\\ComputerName", "ComputerName\UserName", "Password")

    If IsNothing(login) Then



        'do your thing on the shared folder



       PinvokeWindowsNetworking.disconnectRemote("\\ComputerName")

    End If

-1

আমি উত্তরগুলি খুঁজতে এমএসের দিকে চেয়েছিলাম। প্রথম সমাধান ধরে নেওয়া হয় যে অ্যাপ্লিকেশন প্রক্রিয়া চালিত ব্যবহারকারী অ্যাকাউন্টটির ভাগ করা ফোল্ডার বা ড্রাইভে (সেম ডোমেন) অ্যাক্সেস রয়েছে। আপনার ডিএনএস সমাধান হয়েছে তা নিশ্চিত করুন বা আইপি ঠিকানা ব্যবহার করার চেষ্টা করুন। কেবল নিম্নলিখিতটি করুন:

 DirectoryInfo di = new DirectoryInfo(PATH);
 var files = di.EnumerateFiles("*.*", SearchOption.AllDirectories);

আপনি যদি বিভিন্ন ডোমেন জুড়ে চান তবে। শংসাপত্র সহ নেট 2.0 এই মডেলটি অনুসরণ করুন:

WebRequest req = FileWebRequest.Create(new Uri(@"\\<server Name>\Dir\test.txt"));

        req.Credentials = new NetworkCredential(@"<Domain>\<User>", "<Password>");
        req.PreAuthenticate = true;

        WebResponse d = req.GetResponse();
        FileStream fs = File.Create("test.txt");

        // here you can check that the cast was successful if you want. 
        fs = d.GetResponseStream() as FileStream;
        fs.Close();

আকর্ষণীয় দেখায়
ডায়ারস্পটার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.