2010-06-10 2 views
3

DirectoryServices 및 WinNT : // 공급자를 사용하여 원격 컴퓨터에 연결합니다. 그런 다음 그룹 구성원 정보를 확인하고 지정된 로컬 그룹에서 도메인 사용자를 추가하거나 제거 할 수 있습니다.WinNT를 사용하는 원격 컴퓨터에 연결 : // 공급자 및 디렉터리 서비스 사용자 이름/암호를 무시합니다.

vb.net 콘솔 응용 프로그램을 사용하거나 내 로컬 상자 또는 내가 로그인 한 계정에 관리 권한이있는 상자와 통신 할 때이 코드를 모두 사용할 수있었습니다.

코드 :

string strUserPath = "WinNT://DomainName/someuser,user"; 
    DirectoryEntry deComputer = new DirectoryEntry("WinNT://" + Computername + ",computer"); 
    deComputer.RefreshCache(); 
    DirectoryEntry deGroup = deComputer.Children.Find("administrators", "group"); 

    IEnumerable members = deGroup.Invoke("members", null); 
    List<DirectoryEntry> r = new List<DirectoryEntry>(); 

    foreach (object o in members) 
    { 
     DirectoryEntry deMember = new DirectoryEntry(o); 

     r.Add(deMember); 
    } 

    deGroup.Invoke("Add", strUserPath); 
    deGroup.CommitChanges(); 

    deGroup.Invoke("Remove", strUserPath); 
    deGroup.CommitChanges(); 

그래서 나는 Web.config의의로 가장 섹션을 통해 서비스 계정을 사칭하는 ASP.Net 웹 응용 프로그램에 코드를 이동했다.

DirectoryEntry deComputer = new DirectoryEntry("WinNT://" + Computername + ",computer", username, password); 

사용자 이름이있는 도메인 계정의 즉 : 내가 지금처럼 컴퓨터 항목에 대한 생성자에 사용자 이름/암호를 넣어, 그래서 내가 가장하고 있어요 계정은 워크 스테이션 중 하나에서 관리자 권한이 없습니다 모든 워크 스테이션에 대한 로컬 관리자 권한. 결과 deComputer 객체의 Username 속성을 보면 사용자 이름이 입력 한 내용과 일치한다는 것을 알 수 있습니다. 또한 잘못된 암호를 입력하면 오류가 발생하므로 일부 방식으로 인증됩니다.

그러나 원격 워크 스테이션에서 사용자를 추가하거나 제거하려고하면 일반적인 액세스가 거부되었습니다. ASP.Net이 해당 워크 스테이션의 로컬 관리자로 사용하는 서비스 계정을 추가하면 문제가 추가되거나 제거되지 않습니다.

그럼 LogonAPI (advapi32.dll -> LogonUser 호출)를 사용하여 모든 워크 스테이션의 로컬 관리자 인 사용자 계정으로 로그인하고 그 결과 WindowsIdentitiy을 가장하고 원래의 deComputer 인스턴스를 실행 해 보았습니다. 이 작업을 수행 할 때 Path를 제외한 모든 속성이 OLE 예외를 반환합니다 ...

나는 다음에 무엇을 시도 할 것인가에 대해 매우 분실했습니다. 어떤 도움이라도 대단히 감사하겠습니다.

--Workaround--

코드를 실행하는 문제가되지 않습니다, 따라서 우리는 로컬 관리자 계정에서 실행되는 Windows 서비스를 만들어이 문제를 해결하려면합니다. 우리는 모든 업데이트를 SQL 데이터베이스의 테이블로 밀어 넣고 서비스가이를 선택하여 처리합니다. 그러나 이것이 여전히 효과가없는 이유를 알고 싶습니다. 웹 사이트에서 직접 업데이트를 적용하는 것이 좋습니다.

답변

1

사용자 이름과 암호 뒤에 의 추가 매개 변수로 AuthenticationTypes.Secure을 사용하려고 했습니까?

그런데 원격 컴퓨터에 연결하려면 LogonUser을 사용하지 않아야합니다. 올바른 API는 WNetAddConnection2 (http://msdn.microsoft.com/en-us/library/aa385413.aspx 참조) 또는 NetUseAdd은 (http://msdn.microsoft.com/en-us/library/aa370645.aspx 참조)이 이후

+0

나는 AuthenticationTypes.Secure를 시도했지만 성공하지 못했습니다. MSDN의 주요 설명을 읽었을 때 WNetAddConnection2와 같은 소리가 나지 않으며 모든 상황에서 NetUseAdd가 작동합니다. 또한 DirectoryEntry와 함께 어떻게 사용할 수 있습니까? MSDN 기사에서 Logonuser를 사용할 때 얼마나 쉬운 지 알기 쉽지 않은 쉬운 방법은 없었습니다. – Peter

+0

함수'LogonUser'는 로컬 로그인을하지만 원격 로그인이 필요합니다. 예를 들어 HTTPS가있는 은행에 액세스하려면 원하는 은행 계좌로 LogonUser 호출을하지 않고 대상 컴퓨터에서 원격 로그인 만하면됩니다. 같은 것이 여기에서 작동합니다. 대상 컴퓨터가 원본 컴퓨터에 대한 신뢰를 갖지 않거나 대상 컴퓨터에서만 존재하는 (로컬로) 사용자 계정으로 연결하려고하면 LogonUser는 가장이 불가능합니다! 'WNetAddConnection2' 또는'NetUseAdd'를 아무런 문제없이 사용할 수 있습니다. – Oleg

+1

'WNetAddConnection2' 또는'NetUseAdd'와 관련하여 대상 컴퓨터에 연결하면 원격 컴퓨터에 대한 다른 다른 액세스 시도에 사용됩니다. 또한'WinNT' 제공자와 함께'DirectoryEntry'가 그것을 사용할 것입니다. 연결을 끊으려면'WNetCancelConnection2' 또는'NetUseDel'을 사용할 수 있습니다. http://stackoverflow.com/questions/3282927/manage-remote-service-using-alternate-credentials/3348967#3348967에서 자세한 설명을 찾아 볼 수 있습니다. 나는'WNetAddConnection2'와'WNetCancelConnection2'을 시도해 보길 권한다. 그러면 그들이 정확히 당신이 필요로하는 것을 볼 수있을 것이다. – Oleg

0

내가 대답을 분리 C# 다음

에 코드를 변환 한 인기 질문 최종 코드되는 나를 위해 일했다. 이것은 WNetAddConnection2를 사용하여 DirectoryEntry를 사용하기 전에 먼저 연결을 설정합니다.

public static class CredentialSetter 
{ 
    public static void SetCredentials() 
    { 
     string Computername = "SomeComputer"; 
     //Create connection to remote computer' 
     using (NetworkConnection nc = new NetworkConnection("\\\\" + Computername + "", new NetworkCredential("Domain\\Login", "Password"))) 
     { 
      //try connecting using DirectoryEntry to the same machine and add me as a user' 
      string strUserPath = string.Format("WinNT://{0}/{1},user", "DOMAIN", "USER"); 
      DirectoryEntry deGroup = new DirectoryEntry("WinNT://" + Computername + "/Administrators"); 
      deGroup.RefreshCache(); 

      //add and remove the user from the group' 
      deGroup.Invoke("Add", strUserPath); 
      deGroup.CommitChanges(); 
      Console.WriteLine("User Added to computer " + Computername); 

      deGroup.Invoke("Remove", strUserPath); 
      deGroup.CommitChanges(); 
      Console.WriteLine("User Removed from computer " + Computername); 

      deGroup.Close(); 
     } 
     Console.ReadLine(); 
    } 

    public class NetworkConnection : IDisposable 
    { 
     private string _networkName; 
     public NetworkConnection(string networkName, NetworkCredential credentials) 
     { 
      _networkName = networkName; 

      dynamic netResource = new NetResource 
      { 
       Scope = ResourceScope.GlobalNetwork, 
       ResourceType = ResourceType.Disk, 
       DisplayType = ResourceDisplaytype.Share, 
       RemoteName = networkName 
      }; 

      dynamic result = WNetAddConnection2(netResource, credentials.Password, credentials.UserName, 0); 

      if (result != 0) 
      { 
       throw new IOException("Error connecting to remote share", result); 
      } 
     } 

     ~NetworkConnection() 
     { 
      Dispose(false); 
     } 

     public void Dispose() 
     { 
      Dispose(true); 
      GC.SuppressFinalize(this); 
     } 

     protected void Dispose(bool disposing) 
     { 
      WNetCancelConnection2(_networkName, 0, true); 
     } 

     [DllImport("mpr.dll")] 
     private static extern int WNetAddConnection2(NetResource netResource, string password, string username, int flags); 

     [DllImport("mpr.dll")] 
     private static extern int WNetCancelConnection2(string name, int flags, bool force); 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    public class NetResource 
    { 
     public ResourceScope Scope; 
     public ResourceType ResourceType; 
     public ResourceDisplaytype DisplayType; 
     public int Usage; 
     public string LocalName; 
     public string RemoteName; 
     public string Comment; 
     public string Provider; 
    } 

    public enum ResourceScope : int 
    { 
     Connected = 1, 
     GlobalNetwork, 
     Remembered, 
     Recent, 
     Context 
    } 

    public enum ResourceType : int 
    { 
     Any = 0, 
     Disk = 1, 
     Print = 2, 
     Reserved = 8 
    } 

    public enum ResourceDisplaytype : int 
    { 
     Generic = 0x0, 
     Domain = 0x1, 
     Server = 0x2, 
     Share = 0x3, 
     File = 0x4, 
     Group = 0x5, 
     Network = 0x6, 
     Root = 0x7, 
     Shareadmin = 0x8, 
     Directory = 0x9, 
     Tree = 0xa, 
     Ndscontainer = 0xb 
    } 
} 
+0

위의 method.But 시도했지만 올바른 자격 증명을 전달하는 경우에도 액세스가 거부되었습니다. –

-1

오류 (0X80004005) : 지정되지 않은 오류

내가했던 오류 오류 (0X80004005)와 원격 창에 연결하는 몇 가지 문제 : 지정되지 않은 오류입니다. 다음과 같이 해결했습니다.

//Define path 
//This path uses the full path of user authentication 
String path = string.Format("WinNT://{0}/{1},user", server_address, username); 
DirectoryEntry deBase = null; 
try 
{ 
    //Try to connect with secure connection 
    deBase = new DirectoryEntry(path, username, _passwd, AuthenticationTypes.Secure); 

    //Connection test 
    //After test define the deBase with the parent of user (root container) 
    object nativeObject = deBase.NativeObject; 
    deBase = deBase.Parent; 

} 
catch (Exception ex) 
{ 
    //If an error occurred try without Secure Connection 
    try 
    { 
     deBase = new DirectoryEntry(path, username, _passwd); 

     //Connection test 
     //After test define the deBase with the parent of user (root container) 
     object nativeObject = deBase.NativeObject; 
     deBase = deBase.Parent; 
     nativeObject = deBase.NativeObject; 

    } 
    catch (Exception ex2) 
    { 
     //If an error occurred throw the error 
     throw ex2; 
    } 
} 

희망이 있습니다. Helvio Junior www.helviojunior.com.br