MIT Kerberos API调用krb5_mk_req报KDC服务器未找到错误求助
Alright, let's break down why you're hitting that "server not found in Kerberos database" error in krb5_mk_req—it all boils down to a misconfiguration in how you're generating the service principal.
问题根源
你的代码里设置了service = "krbtgt/DOMAIN.COM"和host = "DOMAIN.COM",然后用krb5_sname_to_principal来构建服务主体。但这个函数的设计逻辑是将服务名和主机名组合成完整的主体:
- 比如传入
service = "krbtgt"和host = "DOMAIN.COM",它会生成标准的TGT主体krbtgt/DOMAIN.COM@DOMAIN.COM,这是KDC默认存在的条目。 - 但你把完整的主体前缀
krbtgt/DOMAIN.COM当成服务名传入时,函数会自动把主机名拼接到后面,最终生成畸形的主体:krbtgt/DOMAIN.COM/DOMAIN.COM@DOMAIN.COM。这个主体在你的KDC里根本不存在,所以触发了报错。
你提到kinit -S krbtgt@DOMAIN.COM能正常生成票据,说明你的KDC里可能存在非标准的krbtgt@DOMAIN.COM主体,但代码生成的是完全不同的无效主体,自然无法匹配。
解决方案
方案1:生成标准TGT主体(推荐)
如果你想针对KDC默认的标准TGT主体操作,修正service和host的取值,让krb5_sname_to_principal生成正确的主体:
// 修改service和host的定义 const char service[256] = "krbtgt"; // 仅保留服务名部分 const char host[256] = "DOMAIN.COM"; // 域名作为主机名
这样生成的主体就是krbtgt/DOMAIN.COM@DOMAIN.COM,和KDC中的默认条目完全匹配。
方案2:直接解析完整的服务主体字符串
如果你需要匹配kinit -S krbtgt@DOMAIN.COM用到的非标准主体,可以跳过krb5_sname_to_principal,直接用krb5_parse_name解析完整的主体字符串:
// 替换原有的krb5_sname_to_principal调用逻辑 const char *service_principal_str = "krbtgt@DOMAIN.COM"; err = krb5_parse_name(context, service_principal_str, &service_principal); check_code(err, "parse service principal");
额外逻辑优化建议
需要注意的是:krb5_mk_req的作用是生成针对实际业务服务(比如HTTP、SSH等)的AP-REQ认证请求,而krbtgt是KDC自身的票据授予服务,通常不需要向它发送AP-REQ(你已经通过krb5_get_init_creds_password获取了TGT票据)。如果你的最终目标是访问某个具体服务,应该把service设为对应服务名(比如HTTP),host设为服务所在的主机名(比如server.domain.com),这样生成的主体才是服务对应的合法条目。
内容的提问来源于stack exchange,提问作者cs crypt

