私はC#にかなり慣れていないので、優しくしてください:)
私が達成したいことは、ここで働いている特定のチームが特定の DNS エントリを変更できるように、アプリケーションを作成することです。セキュリティ上の理由から、Active Directory ユーザー アカウントに DNS への変更アクセス権を与えることができず、多くの時間を消費しているため、DNS エントリの変更を避けようとしています。
そのため、DNS エントリを取得および変更するためのいくつかのメソッドを備えた Windows サービスと、Windows サービス メソッドを使用する Windows フォームを作成しました。これは、Windows サービスを Active Directory ユーザー アカウント (サービス アカウント) で実行することを目的としています。このユーザー アカウントは、DNS への変更アクセス権を持ち、通常のユーザー アカウントで Windows フォームを実行します。
管理者アカウント (DNS への変更アクセス権を持つ) としてフォームを実行するとすべて正常に動作しますが、通常のユーザー アカウント (DNS への変更アクセス権を持たない) でフォームを実行すると、例外が発生します。
System.UnauthorizedAccessException: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)
at System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(Int32 errorCode)
at System.Management.ManagementScope.InitializeGuts(Object o)
at System.Management.ManagementScope.Initialize()
at System.Management.ManagementObjectSearcher.Initialize()
at System.Management.ManagementObjectSearcher.Get()
at ChangeDNS.ChangeDNSService.getCName(String cName) in C:\Tools\Projects\ChangeDNSService\ChangeDNSService\Program.cs:line 58
不足しているものと、フォームと Windows サービスの間で資格情報を渡す適切な方法を明らかにするための参照や例を見つけるのに苦労しています。私を正しい方向に向けるのを手伝っていただけませんか。
よろしくお願いいたします。
ダリアン
編集:
フォームには次のコードがあります。
ServiceReference1.ChangeDNSClient dnsClient = new ServiceReference1.ChangeDNSClient();
dnsClient.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
Console.WriteLine(dnsClient.getCName("TestDarianCName1"));
サービスには次のコードがあります。
public string getCName(string cName)
{
serviceLog.Source = serviceName;
string returnServer = "";
try
{
ConnectionOptions connection = new ConnectionOptions();
ManagementScope oMs = new ManagementScope("\\\\" + dnsServer + "\\root \\microsoftdns", connection);
string strQuery = "select * from microsoftdns_" + recType + "Type where containername = '" + domain + "' and OwnerName = '" + cName + "." + domain + "'";
ManagementObjectSearcher oS = new ManagementObjectSearcher(strQuery);
oS.Scope = oMs;
ManagementObjectCollection oRc = oS.Get();
foreach (ManagementObject oR in oRc)
{
returnServer = oR["RecordData"].ToString();
}
}
catch (Exception e)
{
serviceLog.WriteEntry("Exception caught:\n\n" + e.ToString());
}
return returnServer;
}
ManagementObjectCollection oRc = oS.Get(); の行でエラーが発生していると思います。
EDIT2:
クライアントバインディング:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IChangeDNS" />
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8216/ServiceChangeDNS/service"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IChangeDNS"
contract="ServiceReference1.IChangeDNS" name="WSHttpBinding_IChangeDNS">
<identity>
<servicePrincipalName value="host/MyComputerName.domain.local" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
サービスバインディング:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service behaviorConfiguration="ChangeDNSServiceBehavior" name="ChangeDNS.ChangeDNSService">
<endpoint address="" binding="wsHttpBinding" contract="ChangeDNS.IChangeDNS" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8216/ServiceChangeDNS/service" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ChangeDNSServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="False"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>