【发布时间】:2014-02-13 08:28:24
【问题描述】:
这个问题与Starting processes under specific credentials from a Windows service有关,但它是一个不同的问题。
我已在特定凭据下的系统会话 (0) 中从 Windows 服务启动了一个进程,但它无法侦听端口共享 URL。它在 Windows Server 2008 机器上使用“Worker”域帐户。
我的 SMSvcHost.exe.config 文件:http://pastie.org/private/jxed8bdft0eir5uc371pq
我也重新启动了服务和机器,但它仍然给我这个异常:
System.ServiceModel.CommunicationException: The service endpoint failed to listen on the URI 'net.tcp://localhost:5400/Agent/384' because access was denied. Verify that the current user is granted access in the appropriate allowAccounts section of SMSvcHost.exe.config. ---> System.ComponentModel.Win32Exception: Access is denied
at System.ServiceModel.Activation.SharedMemory.Read(String name, String& content)
at System.ServiceModel.Channels.SharedConnectionListener.SharedListenerProxy.ReadEndpoint(String sharedMemoryName, String& listenerEndpoint)
我的 ProcessHelper 代码启动进程:http://pastie.org/private/iytqehsdfujrgil1decda。我正在调用StartAsUserFromService 方法。
我想配置中的 SID 和运行进程的帐户之间的链接不知何故没有建立。但为什么呢?
编辑:
我已经仔细检查了我正在编辑的配置是否已被服务使用。我已经尝试显式添加系统帐户和所有人,但它仍然给我一个拒绝访问错误。就好像它根本不看那个配置一样。
如何找到丢失的权限在哪里?
编辑:
我在机器上重新安装了 .NET 4.5.1 和所有 Windows 更新,但仍然没有成功。
编辑:
这是复制用户令牌以允许其使用端口共享的正确方法吗?特别是SecurityDescriptor 位?
private static ImpersonationResult ImpersonateUser(string domain, string username, string password)
{
IntPtr token = IntPtr.Zero;
IntPtr primaryToken = IntPtr.Zero;
try
{
// Get token
bool bImpersonated = LogonUser(
username,
domain,
password,
(int)LogonType.NetworkClearText,
(int)LogonProvider.Default,
ref token);
if (!bImpersonated)
{
throw new Exception(string.Format("Failed to impersonate identity. Error code: {0}", Marshal.GetLastWin32Error()));
}
SecurityDescriptor sd = new SecurityDescriptor();
IntPtr ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(sd));
Marshal.StructureToPtr(sd, ptr, false);
InitializeSecurityDescriptor(ptr, 1);
sd = (SecurityDescriptor)Marshal.PtrToStructure(ptr, typeof(SecurityDescriptor));
// Set up security
bool bDecriptorSet = SetSecurityDescriptorDacl(
ref sd,
true,
IntPtr.Zero,
false);
if (!bDecriptorSet)
{
throw new Exception(string.Format("Failed to set security descriptor. Error code: {0}", Marshal.GetLastWin32Error()));
}
SecurityAttributes processAttributes = new SecurityAttributes();
processAttributes.lpSecurityDescriptor = ptr;
processAttributes.nLength = (uint)Marshal.SizeOf(sd);
processAttributes.bInheritHandle = true;
// Duplicate token
bool bTokenDuplicated = DuplicateTokenEx(
token,
0,
ref processAttributes,
(int)SecurityImpersonationLevel.SecurityImpersonation,
(int)TokenType.TokenPrimary,
ref primaryToken);
if (!bTokenDuplicated)
{
throw new Exception(string.Format("Failed to duplicate identity token. Error code: {0}", Marshal.GetLastWin32Error()));
}
SecurityAttributes threadAttributes = new SecurityAttributes();
threadAttributes.lpSecurityDescriptor = IntPtr.Zero;
threadAttributes.nLength = 0;
threadAttributes.bInheritHandle = false;
// Got the token
return new ImpersonationResult()
{
Token = primaryToken,
ProcessAttributes = processAttributes,
ThreadAttributes = threadAttributes
};
}
finally
{
FreeToken(token);
}
}
private static void FreeToken(IntPtr token)
{
if (token != IntPtr.Zero)
{
CloseHandle(token);
}
}
编辑:
这是我的进程中启用端口共享的 app.config 位:http://pastie.org/private/8ekqeps4d7rmo7hnktsw
这是启动进程的服务的 app.config 位:http://pastie.org/private/nqqcwz8bvjb5fzp48yavbw。使用端口共享没有问题,因为它是在系统帐户下运行的。
端口共享服务本身是开启的,我已经提到我已经重启了好几次机器了。
“应用服务器”角色没有安装,但是当我去添加它的时候,TCP端口共享角色已经被勾选并显示为灰色,所以肯定是安装了别的东西。 .NET 4.5.1 自带吗?
【问题讨论】:
-
请注意,配置文件附带一个示例
<system.serviceModel.activation>部分已注释掉。在记事本中编辑它,你可能会错过它。确保在该文件中查找<!--和-->。 -
确实配置看起来不错。您是否尝试过不绑定到
localhost而是绑定机器名称?
标签: c# winapi process account net.tcp